mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-09 15:20:56 -06:00
Add infrastructure for generators to select a build tool instance
Add cache entry `CMAKE_GENERATOR_INSTANCE` to hold the instance location persistently across re-runs of CMake in a given build tree. For now we reject the option by default if explicitly set. It will be implemented on a per-generator basis. Pass the setting into try_compile project generation. Add a RunCMake.GeneratorInstance test to cover basic use cases for the option. Verify that `CMAKE_GENERATOR_INSTANCE` is empty by default, and that it is rejected when the generator does not support a user setting. Issue: #17268
This commit is contained in:
@@ -42,6 +42,7 @@ Variables that Provide Information
|
||||
/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION
|
||||
/variable/CMAKE_FIND_PACKAGE_SORT_ORDER
|
||||
/variable/CMAKE_GENERATOR
|
||||
/variable/CMAKE_GENERATOR_INSTANCE
|
||||
/variable/CMAKE_GENERATOR_PLATFORM
|
||||
/variable/CMAKE_GENERATOR_TOOLSET
|
||||
/variable/CMAKE_HOME_DIRECTORY
|
||||
|
||||
7
Help/release/dev/generator-instance.rst
Normal file
7
Help/release/dev/generator-instance.rst
Normal file
@@ -0,0 +1,7 @@
|
||||
generator-instance
|
||||
------------------
|
||||
|
||||
* A :variable:`CMAKE_GENERATOR_INSTANCE` variable was introduced
|
||||
to hold the selected instance of the generator's corresponding
|
||||
native tools if multiple are available. Currently no generators
|
||||
actually use this, but the infrastructure is in place.
|
||||
22
Help/variable/CMAKE_GENERATOR_INSTANCE.rst
Normal file
22
Help/variable/CMAKE_GENERATOR_INSTANCE.rst
Normal file
@@ -0,0 +1,22 @@
|
||||
CMAKE_GENERATOR_INSTANCE
|
||||
------------------------
|
||||
|
||||
Generator-specific instance specification provided by user.
|
||||
|
||||
Some CMake generators support selection of an instance of the native build
|
||||
system when multiple instances are available. If the user specifies an
|
||||
instance (e.g. by setting this cache entry), or after a default instance is
|
||||
chosen when a build tree is first configured, the value will be available in
|
||||
this variable.
|
||||
|
||||
The value of this variable should never be modified by project code.
|
||||
A toolchain file specified by the :variable:`CMAKE_TOOLCHAIN_FILE`
|
||||
variable may initialize ``CMAKE_GENERATOR_INSTANCE`` as a cache entry.
|
||||
Once a given build tree has been initialized with a particular value
|
||||
for this variable, changing the value has undefined behavior.
|
||||
|
||||
Instance specification is supported only on specific generators:
|
||||
|
||||
* None
|
||||
|
||||
See native build system documentation for allowed instance values.
|
||||
@@ -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)
|
||||
{
|
||||
@@ -491,6 +511,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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ macro(add_RunCMake_test test)
|
||||
add_test(NAME RunCMake.${test} COMMAND ${CMAKE_CMAKE_COMMAND}
|
||||
-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_SOURCE_DIR}
|
||||
-DRunCMake_GENERATOR=${CMAKE_GENERATOR}
|
||||
-DRunCMake_GENERATOR_INSTANCE=${CMAKE_GENERATOR_INSTANCE}
|
||||
-DRunCMake_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}
|
||||
-DRunCMake_GENERATOR_TOOLSET=${CMAKE_GENERATOR_TOOLSET}
|
||||
-DRunCMake_MAKE_PROGRAM=${CMake_TEST_EXPLICIT_MAKE_PROGRAM}
|
||||
@@ -47,6 +48,7 @@ function(add_RunCMake_test_group test types)
|
||||
-DTEST_TYPE=${type}
|
||||
-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_SOURCE_DIR}
|
||||
-DRunCMake_GENERATOR=${CMAKE_GENERATOR}
|
||||
-DRunCMake_GENERATOR_INSTANCE=${CMAKE_GENERATOR_INSTANCE}
|
||||
-DRunCMake_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}
|
||||
-DRunCMake_GENERATOR_TOOLSET=${CMAKE_GENERATOR_TOOLSET}
|
||||
-DRunCMake_MAKE_PROGRAM=${CMake_TEST_EXPLICIT_MAKE_PROGRAM}
|
||||
@@ -146,6 +148,7 @@ if(NOT CMAKE_C_COMPILER_ID MATCHES "Watcom")
|
||||
add_RunCMake_test(GenerateExportHeader)
|
||||
endif()
|
||||
add_RunCMake_test(GeneratorExpression)
|
||||
add_RunCMake_test(GeneratorInstance)
|
||||
add_RunCMake_test(GeneratorPlatform)
|
||||
add_RunCMake_test(GeneratorToolset)
|
||||
add_RunCMake_test(GetPrerequisites)
|
||||
|
||||
1
Tests/RunCMake/GeneratorInstance/BadInstance-result.txt
Normal file
1
Tests/RunCMake/GeneratorInstance/BadInstance-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
10
Tests/RunCMake/GeneratorInstance/BadInstance-stderr.txt
Normal file
10
Tests/RunCMake/GeneratorInstance/BadInstance-stderr.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
CMake Error at CMakeLists.txt:[0-9]+ \(project\):
|
||||
Generator
|
||||
|
||||
.*
|
||||
|
||||
does not support instance specification, but instance
|
||||
|
||||
Bad Instance
|
||||
|
||||
was specified.$
|
||||
@@ -0,0 +1 @@
|
||||
set(CMAKE_GENERATOR_INSTANCE "Bad Instance")
|
||||
1
Tests/RunCMake/GeneratorInstance/BadInstance.cmake
Normal file
1
Tests/RunCMake/GeneratorInstance/BadInstance.cmake
Normal file
@@ -0,0 +1 @@
|
||||
message(FATAL_ERROR "This should not be reached!")
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,10 @@
|
||||
CMake Error at CMakeLists.txt:[0-9]+ \(project\):
|
||||
Generator
|
||||
|
||||
.*
|
||||
|
||||
does not support instance specification, but instance
|
||||
|
||||
Bad Instance
|
||||
|
||||
was specified.$
|
||||
@@ -0,0 +1 @@
|
||||
message(FATAL_ERROR "This should not be reached!")
|
||||
3
Tests/RunCMake/GeneratorInstance/CMakeLists.txt
Normal file
3
Tests/RunCMake/GeneratorInstance/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.9)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
||||
1
Tests/RunCMake/GeneratorInstance/NoInstance-result.txt
Normal file
1
Tests/RunCMake/GeneratorInstance/NoInstance-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
4
Tests/RunCMake/GeneratorInstance/NoInstance-stderr.txt
Normal file
4
Tests/RunCMake/GeneratorInstance/NoInstance-stderr.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
CMake Error at NoInstance.cmake:2 \(message\):
|
||||
CMAKE_GENERATOR_INSTANCE is empty as expected.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
7
Tests/RunCMake/GeneratorInstance/NoInstance.cmake
Normal file
7
Tests/RunCMake/GeneratorInstance/NoInstance.cmake
Normal file
@@ -0,0 +1,7 @@
|
||||
if("x${CMAKE_GENERATOR_INSTANCE}" STREQUAL "x")
|
||||
message(FATAL_ERROR "CMAKE_GENERATOR_INSTANCE is empty as expected.")
|
||||
else()
|
||||
message(FATAL_ERROR
|
||||
"CMAKE_GENERATOR_INSTANCE is \"${CMAKE_GENERATOR_INSTANCE}\" "
|
||||
"but should be empty!")
|
||||
endif()
|
||||
11
Tests/RunCMake/GeneratorInstance/RunCMakeTest.cmake
Normal file
11
Tests/RunCMake/GeneratorInstance/RunCMakeTest.cmake
Normal file
@@ -0,0 +1,11 @@
|
||||
include(RunCMake)
|
||||
|
||||
set(RunCMake_GENERATOR_INSTANCE "")
|
||||
run_cmake(NoInstance)
|
||||
|
||||
set(RunCMake_GENERATOR_INSTANCE "Bad Instance")
|
||||
run_cmake(BadInstance)
|
||||
|
||||
set(RunCMake_TEST_OPTIONS -DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/BadInstance-toolchain.cmake)
|
||||
run_cmake(BadInstanceToolchain)
|
||||
unset(RunCMake_TEST_OPTIONS)
|
||||
@@ -79,11 +79,17 @@ function(run_cmake test)
|
||||
${maybe_timeout}
|
||||
)
|
||||
else()
|
||||
if(RunCMake_GENERATOR_INSTANCE)
|
||||
set(_D_CMAKE_GENERATOR_INSTANCE "-DCMAKE_GENERATOR_INSTANCE=${RunCMake_GENERATOR_INSTANCE}")
|
||||
else()
|
||||
set(_D_CMAKE_GENERATOR_INSTANCE "")
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} "${RunCMake_TEST_SOURCE_DIR}"
|
||||
-G "${RunCMake_GENERATOR}"
|
||||
-A "${RunCMake_GENERATOR_PLATFORM}"
|
||||
-T "${RunCMake_GENERATOR_TOOLSET}"
|
||||
${_D_CMAKE_GENERATOR_INSTANCE}
|
||||
-DRunCMake_TEST=${test}
|
||||
--no-warn-unused-cli
|
||||
${RunCMake_TEST_OPTIONS}
|
||||
|
||||
Reference in New Issue
Block a user