diff options
-rw-r--r-- | Help/release/dev/vs-instance.rst | 6 | ||||
-rw-r--r-- | Help/variable/CMAKE_GENERATOR_INSTANCE.rst | 6 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudioVersionedGenerator.cxx | 2 | ||||
-rw-r--r-- | Source/cmVSSetupHelper.cxx | 38 | ||||
-rw-r--r-- | Source/cmVSSetupHelper.h | 1 | ||||
-rw-r--r-- | Tests/RunCMake/GeneratorInstance/PortableNoVersion-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/GeneratorInstance/PortableNoVersion-stderr.txt | 13 | ||||
-rw-r--r-- | Tests/RunCMake/GeneratorInstance/PortableNoVersion.cmake | 1 | ||||
-rw-r--r-- | Tests/RunCMake/GeneratorInstance/RunCMakeTest.cmake | 3 |
9 files changed, 70 insertions, 1 deletions
diff --git a/Help/release/dev/vs-instance.rst b/Help/release/dev/vs-instance.rst new file mode 100644 index 0000000..0b9ff4b --- /dev/null +++ b/Help/release/dev/vs-instance.rst @@ -0,0 +1,6 @@ +vs-instance +----------- + +* The :ref:`Visual Studio Generators` for VS 2017 and above learned to + use portable instances of Visual Studio not known to the VS installer. + See the :variable:`CMAKE_GENERATOR_INSTANCE` variable. diff --git a/Help/variable/CMAKE_GENERATOR_INSTANCE.rst b/Help/variable/CMAKE_GENERATOR_INSTANCE.rst index 3596bf6..6a35f17 100644 --- a/Help/variable/CMAKE_GENERATOR_INSTANCE.rst +++ b/Help/variable/CMAKE_GENERATOR_INSTANCE.rst @@ -44,6 +44,12 @@ Supported pairs are: Specify the 4-component VS Build Version. +.. versionadded:: 3.23 + + A portable VS instance may be specified that is not known to the + Visual Studio Installer tool. The ``location`` and ``version=`` + values must both be provided. + If the value of ``CMAKE_GENERATOR_INSTANCE`` is not specified explicitly by the user or a toolchain file, CMake queries the Visual Studio Installer to locate VS instances, chooses one, and sets the variable as a cache entry diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx index 806871d..f2ce83e 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx +++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx @@ -509,7 +509,7 @@ bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance( cmSystemTools::FileIsDirectory(this->GeneratorInstance)) { e << "\n" "The directory exists, but the instance is not known to the " - "Visual Studio Installer."; + "Visual Studio Installer, and no 'version=' field was given."; } mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); return false; diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx index 39ddce3..cbd241b 100644 --- a/Source/cmVSSetupHelper.cxx +++ b/Source/cmVSSetupHelper.cxx @@ -2,6 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmVSSetupHelper.h" +#include <utility> + #include "cmsys/Encoding.hxx" #include "cmsys/FStream.hxx" @@ -342,6 +344,8 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance() std::string const wantVersion = std::to_string(this->Version) + '.'; + bool specifiedLocationNotSpecifiedVersion = false; + SmartCOMPtr<ISetupInstance> instance; while (SUCCEEDED(enumInstances->Next(1, &instance, NULL)) && instance) { SmartCOMPtr<ISetupInstance2> instance2 = NULL; @@ -373,6 +377,7 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance() chosenInstanceInfo = instanceInfo; return true; } + specifiedLocationNotSpecifiedVersion = true; } } else if (!this->SpecifiedVSInstallVersion.empty()) { // We are looking for a specific version. @@ -398,6 +403,13 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance() } } + if (!this->SpecifiedVSInstallLocation.empty() && + !specifiedLocationNotSpecifiedVersion) { + // The VS Installer does not know about the specified location. + // Check for one directly on disk. + return this->LoadSpecifiedVSInstanceFromDisk(); + } + if (vecVSInstances.size() > 0) { isVSInstanceExists = true; int index = ChooseVSInstance(vecVSInstances); @@ -460,6 +472,32 @@ int cmVSSetupAPIHelper::ChooseVSInstance( return chosenIndex; } +bool cmVSSetupAPIHelper::LoadSpecifiedVSInstanceFromDisk() +{ + if (!cmSystemTools::FileIsDirectory(this->SpecifiedVSInstallLocation)) { + return false; + } + VSInstanceInfo vsInstanceInfo; + vsInstanceInfo.VSInstallLocation = this->SpecifiedVSInstallLocation; + // FIXME: Is there a better way to get SDK information? + vsInstanceInfo.IsWin10SDKInstalled = true; + vsInstanceInfo.IsWin81SDKInstalled = false; + + if (!this->SpecifiedVSInstallVersion.empty()) { + // Assume the version specified by the user is correct. + vsInstanceInfo.Version = this->SpecifiedVSInstallVersion; + } else { + return false; + } + + if (!LoadVSInstanceVCToolsetVersion(vsInstanceInfo)) { + return false; + } + + chosenInstanceInfo = std::move(vsInstanceInfo); + return true; +} + bool cmVSSetupAPIHelper::Initialize() { if (initializationFailure) diff --git a/Source/cmVSSetupHelper.h b/Source/cmVSSetupHelper.h index d7e82d0..44c883b 100644 --- a/Source/cmVSSetupHelper.h +++ b/Source/cmVSSetupHelper.h @@ -117,6 +117,7 @@ private: bool& bWin10SDK, bool& bWin81SDK); int ChooseVSInstance(const std::vector<VSInstanceInfo>& vecVSInstances); bool EnumerateAndChooseVSInstance(); + bool LoadSpecifiedVSInstanceFromDisk(); unsigned int Version; diff --git a/Tests/RunCMake/GeneratorInstance/PortableNoVersion-result.txt b/Tests/RunCMake/GeneratorInstance/PortableNoVersion-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorInstance/PortableNoVersion-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorInstance/PortableNoVersion-stderr.txt b/Tests/RunCMake/GeneratorInstance/PortableNoVersion-stderr.txt new file mode 100644 index 0000000..baa17aa --- /dev/null +++ b/Tests/RunCMake/GeneratorInstance/PortableNoVersion-stderr.txt @@ -0,0 +1,13 @@ +^CMake Error at CMakeLists.txt:[0-9]+ \(project\): + Generator + + Visual Studio [^ +]+ + + could not find specified instance of Visual Studio: + + [^ +]+/Tests/RunCMake/GeneratorInstance + + The directory exists, but the instance is not known to the Visual Studio + Installer, and no 'version=' field was given\.$ diff --git a/Tests/RunCMake/GeneratorInstance/PortableNoVersion.cmake b/Tests/RunCMake/GeneratorInstance/PortableNoVersion.cmake new file mode 100644 index 0000000..2fc38e5 --- /dev/null +++ b/Tests/RunCMake/GeneratorInstance/PortableNoVersion.cmake @@ -0,0 +1 @@ +message(FATAL_ERROR "This should not be reached!") diff --git a/Tests/RunCMake/GeneratorInstance/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorInstance/RunCMakeTest.cmake index cdcaac8..dfcdcf8 100644 --- a/Tests/RunCMake/GeneratorInstance/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorInstance/RunCMakeTest.cmake @@ -32,6 +32,9 @@ if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio (1[56789])") set(RunCMake_GENERATOR_INSTANCE "${default_instance},version=${vs_major}.999.99999.999") run_cmake(WrongVersion) endif() + + set(RunCMake_GENERATOR_INSTANCE "${RunCMake_SOURCE_DIR}") + run_cmake(PortableNoVersion) else() set(RunCMake_GENERATOR_INSTANCE "") run_cmake(NoInstance) |