diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeVersion.cmake | 2 | ||||
-rw-r--r-- | Source/cmCMakeHostSystemInformationCommand.cxx | 14 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 27 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.h | 3 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio15Generator.cxx | 47 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio15Generator.h | 5 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 1 | ||||
-rw-r--r-- | Source/cmVSSetupHelper.cxx | 36 | ||||
-rw-r--r-- | Source/cmVSSetupHelper.h | 4 | ||||
-rw-r--r-- | Source/cmake.cxx | 27 | ||||
-rw-r--r-- | Source/cmake.h | 7 |
11 files changed, 161 insertions, 12 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index d0d95b4..306f4c4 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 10) -set(CMake_VERSION_PATCH 20171019) +set(CMake_VERSION_PATCH 20171025) #set(CMake_VERSION_RC 1) diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx index 5106f52..662dd74 100644 --- a/Source/cmCMakeHostSystemInformationCommand.cxx +++ b/Source/cmCMakeHostSystemInformationCommand.cxx @@ -8,6 +8,9 @@ #include "cmsys/SystemInformation.hxx" #if defined(_WIN32) +#include "cmAlgorithms.h" +#include "cmGlobalGenerator.h" +#include "cmGlobalVisualStudio15Generator.h" #include "cmSystemTools.h" #include "cmVSSetupHelper.h" #define HAVE_VS_SETUP_HELPER @@ -127,6 +130,17 @@ bool cmCMakeHostSystemInformationCommand::GetValue( value = this->ValueToString(info.GetOSPlatform()); #ifdef HAVE_VS_SETUP_HELPER } else if (key == "VS_15_DIR") { + // If generating for the VS 15 IDE, use the same instance. + cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator(); + if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 15 ")) { + cmGlobalVisualStudio15Generator* vs15gen = + static_cast<cmGlobalVisualStudio15Generator*>(gg); + if (vs15gen->GetVSInstance(value)) { + return true; + } + } + + // Otherwise, find a VS 15 instance ourselves. cmVSSetupAPIHelper vsSetupAPIHelper; if (vsSetupAPIHelper.GetVSInstanceInfo(value)) { cmSystemTools::ConvertToUnixSlashes(value); diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 000309f..e0100ce 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -111,6 +111,26 @@ cmGlobalGenerator::~cmGlobalGenerator() delete this->ExtraGenerator; } +bool cmGlobalGenerator::SetGeneratorInstance(std::string const& i, + cmMakefile* mf) +{ + if (i.empty()) { + return true; + } + + std::ostringstream e; + /* clang-format off */ + e << + "Generator\n" + " " << this->GetName() << "\n" + "does not support instance specification, but instance\n" + " " << i << "\n" + "was specified."; + /* clang-format on */ + mf->IssueMessage(cmake::FATAL_ERROR, e.str()); + return false; +} + bool cmGlobalGenerator::SetGeneratorPlatform(std::string const& p, cmMakefile* mf) { @@ -528,6 +548,13 @@ void cmGlobalGenerator::EnableLanguage( } if (readCMakeSystem) { + // Tell the generator about the instance, if any. + std::string instance = mf->GetSafeDefinition("CMAKE_GENERATOR_INSTANCE"); + if (!this->SetGeneratorInstance(instance, mf)) { + cmSystemTools::SetFatalErrorOccured(); + return; + } + // Find the native build tool for this generator. if (!this->FindMakeProgram(mf)) { return; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 1f90ecf..c5a5297 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -70,6 +70,9 @@ public: /** Tell the generator about the target system. */ virtual bool SetSystemName(std::string const&, cmMakefile*) { return true; } + /** Set the generator-specific instance. Returns true if supported. */ + virtual bool SetGeneratorInstance(std::string const& i, cmMakefile* mf); + /** Set the generator-specific platform name. Returns true if platform is supported and false otherwise. */ virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf); diff --git a/Source/cmGlobalVisualStudio15Generator.cxx b/Source/cmGlobalVisualStudio15Generator.cxx index d2bf7cc..014d93d 100644 --- a/Source/cmGlobalVisualStudio15Generator.cxx +++ b/Source/cmGlobalVisualStudio15Generator.cxx @@ -111,6 +111,53 @@ void cmGlobalVisualStudio15Generator::WriteSLNHeader(std::ostream& fout) } } +bool cmGlobalVisualStudio15Generator::SetGeneratorInstance( + std::string const& i, cmMakefile* mf) +{ + if (!i.empty()) { + if (!this->vsSetupAPIHelper.SetVSInstance(i)) { + std::ostringstream e; + /* clang-format off */ + e << + "Generator\n" + " " << this->GetName() << "\n" + "could not find specified instance of Visual Studio:\n" + " " << i; + /* clang-format on */ + mf->IssueMessage(cmake::FATAL_ERROR, e.str()); + return false; + } + } + + std::string vsInstance; + if (!this->vsSetupAPIHelper.GetVSInstanceInfo(vsInstance)) { + std::ostringstream e; + /* clang-format off */ + e << + "Generator\n" + " " << this->GetName() << "\n" + "could not find any instance of Visual Studio.\n"; + /* clang-format on */ + mf->IssueMessage(cmake::FATAL_ERROR, e.str()); + return false; + } + + // Save the selected instance persistently. + std::string genInstance = mf->GetSafeDefinition("CMAKE_GENERATOR_INSTANCE"); + if (vsInstance != genInstance) { + this->CMakeInstance->AddCacheEntry( + "CMAKE_GENERATOR_INSTANCE", vsInstance.c_str(), + "Generator instance identifier.", cmStateEnums::INTERNAL); + } + + return true; +} + +bool cmGlobalVisualStudio15Generator::GetVSInstance(std::string& dir) const +{ + return vsSetupAPIHelper.GetVSInstanceInfo(dir); +} + bool cmGlobalVisualStudio15Generator::InitializeWindows(cmMakefile* mf) { // If the Win 8.1 SDK is installed then we can select a SDK matching diff --git a/Source/cmGlobalVisualStudio15Generator.h b/Source/cmGlobalVisualStudio15Generator.h index e934882..852a4e7 100644 --- a/Source/cmGlobalVisualStudio15Generator.h +++ b/Source/cmGlobalVisualStudio15Generator.h @@ -27,6 +27,11 @@ public: virtual void WriteSLNHeader(std::ostream& fout); virtual const char* GetToolsVersion() { return "15.0"; } + + bool SetGeneratorInstance(std::string const& i, cmMakefile* mf) override; + + bool GetVSInstance(std::string& dir) const; + protected: bool InitializeWindows(cmMakefile* mf) override; virtual bool SelectWindowsStoreToolset(std::string& toolset) const; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 5643c97..b2641d2 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -3186,6 +3186,7 @@ int cmMakefile::TryCompile(const std::string& srcdir, // do a configure cm.SetHomeDirectory(srcdir); cm.SetHomeOutputDirectory(bindir); + cm.SetGeneratorInstance(this->GetSafeDefinition("CMAKE_GENERATOR_INSTANCE")); cm.SetGeneratorPlatform(this->GetSafeDefinition("CMAKE_GENERATOR_PLATFORM")); cm.SetGeneratorToolset(this->GetSafeDefinition("CMAKE_GENERATOR_TOOLSET")); cm.LoadCache(); diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx index ea13649..c2f8deb 100644 --- a/Source/cmVSSetupHelper.cxx +++ b/Source/cmVSSetupHelper.cxx @@ -80,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(); @@ -265,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; @@ -296,16 +297,29 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance() instance = instance2 = NULL; if (isInstalled) { - if (!envVSCommonToolsDir.empty()) { + if (!this->SpecifiedVSInstallLocation.empty()) { + // We are looking for a specific instance. std::string currentVSLocation = instanceInfo.GetInstallLocation(); - currentVSLocation += "/Common7/Tools"; 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); } } diff --git a/Source/cmVSSetupHelper.h b/Source/cmVSSetupHelper.h index 74a7ec0..c07cfaf 100644 --- a/Source/cmVSSetupHelper.h +++ b/Source/cmVSSetupHelper.h @@ -126,6 +126,8 @@ public: cmVSSetupAPIHelper(); ~cmVSSetupAPIHelper(); + bool SetVSInstance(std::string const& vsInstallLocation); + bool IsVS2017Installed(); bool GetVSInstanceInfo(std::string& vsInstallLocation); bool IsWin10SDKInstalled(); @@ -150,6 +152,8 @@ private: HRESULT comInitialized; // current best instance of VS selected VSInstanceInfo chosenInstanceInfo; + + std::string SpecifiedVSInstallLocation; }; #endif diff --git a/Source/cmake.cxx b/Source/cmake.cxx index d7ed772..cd714c6 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -1326,6 +1326,25 @@ int cmake::ActualConfigure() cmStateEnums::INTERNAL); } + if (const char* instance = + this->State->GetInitializedCacheValue("CMAKE_GENERATOR_INSTANCE")) { + if (!this->GeneratorInstance.empty() && + this->GeneratorInstance != instance) { + std::string message = "Error: generator instance: "; + message += this->GeneratorInstance; + message += "\nDoes not match the instance used previously: "; + message += instance; + message += "\nEither remove the CMakeCache.txt file and CMakeFiles " + "directory or choose a different binary directory."; + cmSystemTools::Error(message.c_str()); + return -2; + } + } else { + this->AddCacheEntry( + "CMAKE_GENERATOR_INSTANCE", this->GeneratorInstance.c_str(), + "Generator instance identifier.", cmStateEnums::INTERNAL); + } + if (const char* platformName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR_PLATFORM")) { if (!this->GeneratorPlatform.empty() && @@ -2360,6 +2379,14 @@ int cmake::Build(const std::string& dir, const std::string& target, << "\"\n"; return 1; } + const char* cachedGeneratorInstance = + this->State->GetCacheEntryValue("CMAKE_GENERATOR_INSTANCE"); + if (cachedGeneratorInstance) { + cmMakefile mf(gen.get(), this->GetCurrentSnapshot()); + if (!gen->SetGeneratorInstance(cachedGeneratorInstance, &mf)) { + return 1; + } + } std::string output; std::string projName; const char* cachedProjectName = diff --git a/Source/cmake.h b/Source/cmake.h index ed3ebe0..5c5a90d 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -203,6 +203,12 @@ public: ///! Get the names of the current registered generators void GetRegisteredGenerators(std::vector<GeneratorInfo>& generators) const; + ///! Set the name of the selected generator-specific instance. + void SetGeneratorInstance(std::string const& instance) + { + this->GeneratorInstance = instance; + } + ///! Set the name of the selected generator-specific platform. void SetGeneratorPlatform(std::string const& ts) { @@ -431,6 +437,7 @@ protected: cmGlobalGenerator* GlobalGenerator; std::map<std::string, DiagLevel> DiagLevels; + std::string GeneratorInstance; std::string GeneratorPlatform; std::string GeneratorToolset; |