From da59d7769e1f432c8366799dadfd3b0b6268dd67 Mon Sep 17 00:00:00 2001 From: Alexandre Zollinger Chohfi Date: Wed, 21 Oct 2026 14:55:30 -0700 Subject: [PATCH] cmake: Find the default generator only when printing the generator list `cmake --version` and the other documentation options build the generator documentation even when they do not print it. That evaluates the default generator, which on Windows queries the Visual Studio Setup COM API for VS 18, 17, 16 and 15 in turn and constructs the newest Visual Studio generator found. It makes `cmake --version` take about 100 ms on Windows, which is a lot for a command that tools run often to detect CMake. Only `--help` and the generator listing print generators. Evaluate them only for those requests. Fixes: #28220 --- Source/cmDocumentation.cxx | 10 ++++++++++ Source/cmDocumentation.h | 3 +++ Source/cmakemain.cxx | 7 ++++++- .../RunCMake/CommandLine/Envgen-bad-version-stdout.txt | 1 + Tests/RunCMake/CommandLine/RunCMakeTest.cmake | 2 ++ 5 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 Tests/RunCMake/CommandLine/Envgen-bad-version-stdout.txt diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index ae00e781e3..5e4fd4d2de 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -207,6 +207,16 @@ bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os) } } +bool cmDocumentation::RequestsGenerators() const +{ + return std::any_of(this->RequestedHelpItems.begin(), + this->RequestedHelpItems.end(), + [this](RequestedHelpItem const& rhi) { + return rhi.HelpType == ListGenerators || + (rhi.HelpType == Help && this->ShowGenerators); + }); +} + bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os) { int count = 0; diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h index e23cee9fe9..fef086327f 100644 --- a/Source/cmDocumentation.h +++ b/Source/cmDocumentation.h @@ -73,6 +73,9 @@ public: void SetShowGenerators(bool showGen) { this->ShowGenerators = showGen; } + /** Whether the requested documentation prints the generator list. */ + bool RequestsGenerators() const; + /** Set the program name for standard document generation. */ void SetName(std::string const& name); diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 00056bfcf5..a49afecfe0 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -237,7 +237,12 @@ int do_cmake(int ac, char const* const* av) std::vector args(av, av + ac); hcm.SetCacheArgs(args); - auto generators = hcm.GetGeneratorsDocumentation(); + // Finding the default generator can query Visual Studio instances, + // so do it only when the generator list will be printed. + std::vector generators; + if (doc.RequestsGenerators()) { + generators = hcm.GetGeneratorsDocumentation(); + } doc.SetName("cmake"); doc.SetSection("Name", cmDocumentationName); diff --git a/Tests/RunCMake/CommandLine/Envgen-bad-version-stdout.txt b/Tests/RunCMake/CommandLine/Envgen-bad-version-stdout.txt new file mode 100644 index 0000000000..6d99b049bf --- /dev/null +++ b/Tests/RunCMake/CommandLine/Envgen-bad-version-stdout.txt @@ -0,0 +1 @@ +^cmake version [0-9] diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index 8dd85730ab..b2ecbc588b 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -463,6 +463,8 @@ function(run_EnvironmentGenerator) run_cmake_command(Envgen-ninja-multi-help ${CMAKE_COMMAND} --help) set(ENV{CMAKE_GENERATOR} "NoSuchGenerator") run_cmake_command(Envgen-bad-help ${CMAKE_COMMAND} --help) + # --version does not print generators, so it does not evaluate them + run_cmake_command(Envgen-bad-version ${CMAKE_COMMAND} --version) unset(ENV{CMAKE_GENERATOR}) if(RunCMake_GENERATOR MATCHES "Visual Studio")