mirror of
https://github.com/Kitware/CMake.git
synced 2026-04-22 14:23:10 -05:00
VS: Allow CMAKE_GENERATOR_INSTANCE to specify portable instance
Previously the `CMAKE_GENERATOR_INSTANCE` value was used only to filter the instances reported by the Visual Studio Installer tool. If the specified install location is not known to the VS Installer, but the user provided a `version=` field, check for the installation directly on disk. Fixes: #21639, #22197
This commit is contained in:
@@ -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.
|
||||||
@@ -44,6 +44,12 @@ Supported pairs are:
|
|||||||
|
|
||||||
Specify the 4-component VS Build Version.
|
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
|
If the value of ``CMAKE_GENERATOR_INSTANCE`` is not specified explicitly
|
||||||
by the user or a toolchain file, CMake queries the Visual Studio Installer
|
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
|
to locate VS instances, chooses one, and sets the variable as a cache entry
|
||||||
|
|||||||
@@ -509,7 +509,7 @@ bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance(
|
|||||||
cmSystemTools::FileIsDirectory(this->GeneratorInstance)) {
|
cmSystemTools::FileIsDirectory(this->GeneratorInstance)) {
|
||||||
e << "\n"
|
e << "\n"
|
||||||
"The directory exists, but the instance is not known to the "
|
"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());
|
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||||
#include "cmVSSetupHelper.h"
|
#include "cmVSSetupHelper.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "cmsys/Encoding.hxx"
|
#include "cmsys/Encoding.hxx"
|
||||||
#include "cmsys/FStream.hxx"
|
#include "cmsys/FStream.hxx"
|
||||||
|
|
||||||
@@ -342,6 +344,8 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
|
|||||||
|
|
||||||
std::string const wantVersion = std::to_string(this->Version) + '.';
|
std::string const wantVersion = std::to_string(this->Version) + '.';
|
||||||
|
|
||||||
|
bool specifiedLocationNotSpecifiedVersion = false;
|
||||||
|
|
||||||
SmartCOMPtr<ISetupInstance> instance;
|
SmartCOMPtr<ISetupInstance> instance;
|
||||||
while (SUCCEEDED(enumInstances->Next(1, &instance, NULL)) && instance) {
|
while (SUCCEEDED(enumInstances->Next(1, &instance, NULL)) && instance) {
|
||||||
SmartCOMPtr<ISetupInstance2> instance2 = NULL;
|
SmartCOMPtr<ISetupInstance2> instance2 = NULL;
|
||||||
@@ -373,6 +377,7 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
|
|||||||
chosenInstanceInfo = instanceInfo;
|
chosenInstanceInfo = instanceInfo;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
specifiedLocationNotSpecifiedVersion = true;
|
||||||
}
|
}
|
||||||
} else if (!this->SpecifiedVSInstallVersion.empty()) {
|
} else if (!this->SpecifiedVSInstallVersion.empty()) {
|
||||||
// We are looking for a specific version.
|
// 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) {
|
if (vecVSInstances.size() > 0) {
|
||||||
isVSInstanceExists = true;
|
isVSInstanceExists = true;
|
||||||
int index = ChooseVSInstance(vecVSInstances);
|
int index = ChooseVSInstance(vecVSInstances);
|
||||||
@@ -460,6 +472,32 @@ int cmVSSetupAPIHelper::ChooseVSInstance(
|
|||||||
return chosenIndex;
|
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()
|
bool cmVSSetupAPIHelper::Initialize()
|
||||||
{
|
{
|
||||||
if (initializationFailure)
|
if (initializationFailure)
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ private:
|
|||||||
bool& bWin10SDK, bool& bWin81SDK);
|
bool& bWin10SDK, bool& bWin81SDK);
|
||||||
int ChooseVSInstance(const std::vector<VSInstanceInfo>& vecVSInstances);
|
int ChooseVSInstance(const std::vector<VSInstanceInfo>& vecVSInstances);
|
||||||
bool EnumerateAndChooseVSInstance();
|
bool EnumerateAndChooseVSInstance();
|
||||||
|
bool LoadSpecifiedVSInstanceFromDisk();
|
||||||
|
|
||||||
unsigned int Version;
|
unsigned int Version;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
@@ -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\.$
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
message(FATAL_ERROR "This should not be reached!")
|
||||||
@@ -32,6 +32,9 @@ if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio (1[56789])")
|
|||||||
set(RunCMake_GENERATOR_INSTANCE "${default_instance},version=${vs_major}.999.99999.999")
|
set(RunCMake_GENERATOR_INSTANCE "${default_instance},version=${vs_major}.999.99999.999")
|
||||||
run_cmake(WrongVersion)
|
run_cmake(WrongVersion)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(RunCMake_GENERATOR_INSTANCE "${RunCMake_SOURCE_DIR}")
|
||||||
|
run_cmake(PortableNoVersion)
|
||||||
else()
|
else()
|
||||||
set(RunCMake_GENERATOR_INSTANCE "")
|
set(RunCMake_GENERATOR_INSTANCE "")
|
||||||
run_cmake(NoInstance)
|
run_cmake(NoInstance)
|
||||||
|
|||||||
Reference in New Issue
Block a user