summaryrefslogtreecommitdiffstats
path: root/Source/cmVSSetupHelper.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmVSSetupHelper.cxx')
-rw-r--r--Source/cmVSSetupHelper.cxx98
1 files changed, 63 insertions, 35 deletions
diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx
index 7168f26..c2f8deb 100644
--- a/Source/cmVSSetupHelper.cxx
+++ b/Source/cmVSSetupHelper.cxx
@@ -1,7 +1,10 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmVSSetupHelper.h"
+
#include "cmSystemTools.h"
+#include "cmsys/Encoding.hxx"
+#include "cmsys/FStream.hxx"
#ifndef VSSetupConstants
#define VSSetupConstants
@@ -41,14 +44,19 @@ const CLSID CLSID_SetupConfiguration = {
/* clang-format on */
#endif
-const WCHAR* VCToolsetComponent =
- L"Microsoft.VisualStudio.Component.VC.Tools.x86.x64";
const WCHAR* Win10SDKComponent =
L"Microsoft.VisualStudio.Component.Windows10SDK";
const WCHAR* Win81SDKComponent =
L"Microsoft.VisualStudio.Component.Windows81SDK";
const WCHAR* ComponentType = L"Component";
+std::string VSInstanceInfo::GetInstallLocation() const
+{
+ std::string loc = cmsys::Encoding::ToNarrow(this->VSInstallLocation);
+ cmSystemTools::ConvertToUnixSlashes(loc);
+ return loc;
+}
+
cmVSSetupAPIHelper::cmVSSetupAPIHelper()
: setupConfig(NULL)
, setupConfig2(NULL)
@@ -72,6 +80,14 @@ cmVSSetupAPIHelper::~cmVSSetupAPIHelper()
CoUninitialize();
}
+bool cmVSSetupAPIHelper::SetVSInstance(std::string const& vsInstallLocation)
+{
+ this->SpecifiedVSInstallLocation = vsInstallLocation;
+ cmSystemTools::ConvertToUnixSlashes(this->SpecifiedVSInstallLocation);
+ chosenInstanceInfo = VSInstanceInfo();
+ return this->EnumerateAndChooseVSInstance();
+}
+
bool cmVSSetupAPIHelper::IsVS2017Installed()
{
return this->EnumerateAndChooseVSInstance();
@@ -90,11 +106,11 @@ bool cmVSSetupAPIHelper::IsWin81SDKInstalled()
}
bool cmVSSetupAPIHelper::CheckInstalledComponent(
- SmartCOMPtr<ISetupPackageReference> package, bool& bVCToolset,
- bool& bWin10SDK, bool& bWin81SDK)
+ SmartCOMPtr<ISetupPackageReference> package, bool& bWin10SDK,
+ bool& bWin81SDK)
{
bool ret = false;
- bVCToolset = bWin10SDK = bWin81SDK = false;
+ bWin10SDK = bWin81SDK = false;
SmartBSTR bstrId;
if (FAILED(package->GetId(&bstrId))) {
return ret;
@@ -107,11 +123,6 @@ bool cmVSSetupAPIHelper::CheckInstalledComponent(
std::wstring id = std::wstring(bstrId);
std::wstring type = std::wstring(bstrType);
- if (id.compare(VCToolsetComponent) == 0 &&
- type.compare(ComponentType) == 0) {
- bVCToolset = true;
- ret = true;
- }
// Checks for any version of Win10 SDK. The version is appended at the end of
// the
@@ -135,7 +146,6 @@ bool cmVSSetupAPIHelper::CheckInstalledComponent(
bool cmVSSetupAPIHelper::GetVSInstanceInfo(
SmartCOMPtr<ISetupInstance2> pInstance, VSInstanceInfo& vsInstanceInfo)
{
- bool isVCToolSetInstalled = false;
if (pInstance == NULL)
return false;
@@ -174,6 +184,23 @@ bool cmVSSetupAPIHelper::GetVSInstanceInfo(
}
}
+ // Check if a compiler is installed with this instance.
+ {
+ std::string const vcRoot = vsInstanceInfo.GetInstallLocation();
+ std::string const vcToolsVersionFile =
+ vcRoot + "/VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt";
+ std::string vcToolsVersion;
+ cmsys::ifstream fin(vcToolsVersionFile.c_str());
+ if (!fin || !cmSystemTools::GetLineFromStream(fin, vcToolsVersion)) {
+ return false;
+ }
+ vcToolsVersion = cmSystemTools::TrimWhitespace(vcToolsVersion);
+ std::string const vcToolsDir = vcRoot + "/VC/Tools/MSVC/" + vcToolsVersion;
+ if (!cmSystemTools::FileIsDirectory(vcToolsDir)) {
+ return false;
+ }
+ }
+
// Reboot may have been required before the product package was registered
// (last).
if ((eRegistered & state) == eRegistered) {
@@ -199,12 +226,11 @@ bool cmVSSetupAPIHelper::GetVSInstanceInfo(
package == NULL)
continue;
- bool vcToolsetInstalled = false, win10SDKInstalled = false,
- win81SDkInstalled = false;
- bool ret = CheckInstalledComponent(package, vcToolsetInstalled,
- win10SDKInstalled, win81SDkInstalled);
+ bool win10SDKInstalled = false;
+ bool win81SDkInstalled = false;
+ bool ret =
+ CheckInstalledComponent(package, win10SDKInstalled, win81SDkInstalled);
if (ret) {
- isVCToolSetInstalled |= vcToolsetInstalled;
vsInstanceInfo.IsWin10SDKInstalled |= win10SDKInstalled;
vsInstanceInfo.IsWin81SDKInstalled |= win81SDkInstalled;
}
@@ -213,18 +239,16 @@ bool cmVSSetupAPIHelper::GetVSInstanceInfo(
SafeArrayDestroy(lpsaPackages);
}
- return isVCToolSetInstalled;
+ return true;
}
bool cmVSSetupAPIHelper::GetVSInstanceInfo(std::string& vsInstallLocation)
{
- vsInstallLocation = "";
+ vsInstallLocation.clear();
bool isInstalled = this->EnumerateAndChooseVSInstance();
if (isInstalled) {
- std::string str(chosenInstanceInfo.VSInstallLocation.begin(),
- chosenInstanceInfo.VSInstallLocation.end());
- vsInstallLocation = str;
+ vsInstallLocation = chosenInstanceInfo.GetInstallLocation();
}
return isInstalled;
@@ -249,13 +273,6 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
if (cmSystemTools::GetEnv("VS150COMNTOOLS", envVSCommonToolsDir)) {
cmSystemTools::ConvertToUnixSlashes(envVSCommonToolsDir);
}
- // FIXME: If the environment variable value changes between runs
- // of CMake within a given build tree the results are not defined.
- // Instead we should save a CMAKE_GENERATOR_INSTANCE value in the cache
- // (similar to CMAKE_GENERATOR_TOOLSET) to hold it persistently.
- // Unfortunately doing so will require refactoring elsewhere in
- // order to make sure the value is available in time to create
- // the generator.
std::vector<VSInstanceInfo> vecVSInstances;
SmartCOMPtr<IEnumSetupInstances> enumInstances = NULL;
@@ -280,18 +297,29 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
instance = instance2 = NULL;
if (isInstalled) {
- if (!envVSCommonToolsDir.empty()) {
- std::string currentVSLocation(instanceInfo.VSInstallLocation.begin(),
- instanceInfo.VSInstallLocation.end());
- cmSystemTools::ConvertToUnixSlashes(currentVSLocation);
- currentVSLocation += "/Common7/Tools";
+ if (!this->SpecifiedVSInstallLocation.empty()) {
+ // We are looking for a specific instance.
+ std::string currentVSLocation = instanceInfo.GetInstallLocation();
if (cmSystemTools::ComparePath(currentVSLocation,
- envVSCommonToolsDir)) {
+ this->SpecifiedVSInstallLocation)) {
chosenInstanceInfo = instanceInfo;
return true;
}
+ } else {
+ // We are not looking for a specific instance.
+ // If we've been given a hint then use it.
+ if (!envVSCommonToolsDir.empty()) {
+ std::string currentVSLocation = instanceInfo.GetInstallLocation();
+ currentVSLocation += "/Common7/Tools";
+ if (cmSystemTools::ComparePath(currentVSLocation,
+ envVSCommonToolsDir)) {
+ chosenInstanceInfo = instanceInfo;
+ return true;
+ }
+ }
+ // Otherwise, add this to the list of candidates.
+ vecVSInstances.push_back(instanceInfo);
}
- vecVSInstances.push_back(instanceInfo);
}
}