summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/release/dev/vs-instance.rst6
-rw-r--r--Help/variable/CMAKE_GENERATOR_INSTANCE.rst6
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx2
-rw-r--r--Source/cmVSSetupHelper.cxx38
-rw-r--r--Source/cmVSSetupHelper.h1
-rw-r--r--Tests/RunCMake/GeneratorInstance/PortableNoVersion-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorInstance/PortableNoVersion-stderr.txt13
-rw-r--r--Tests/RunCMake/GeneratorInstance/PortableNoVersion.cmake1
-rw-r--r--Tests/RunCMake/GeneratorInstance/RunCMakeTest.cmake3
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)