mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
cmake: Add cached environment id that triggers reconfigure when changed
The opaque `CMAKE_SYSTEM_ENVIRONMENT_ID` variable is cached during the first invocation of `cmake` and is a user-defined hint about the state of the environment. When the value changes, `cmake` either does nothing, emits a warning (by default), or refreshes the cache as if by `--fresh`. The action is controlled by the `CMAKE_SYSTEM_ENVIRONMENT_ACTION` environment variable (which is not cached). Implements: #28025
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
CMAKE_SYSTEM_ENVIRONMENT_ACTION
|
||||
-------------------------------
|
||||
|
||||
.. versionadded:: 4.5
|
||||
|
||||
.. include:: include/ENV_VAR.rst
|
||||
|
||||
Specify the action taken by :manual:`cmake(1)` when the value of
|
||||
:envvar:`CMAKE_SYSTEM_ENVIRONMENT_ID` in the environment does not match the
|
||||
cached value. If not set, the default is ``WARN``.
|
||||
|
||||
The value may be one of:
|
||||
|
||||
``IGNORE``
|
||||
No action is taken.
|
||||
|
||||
``WARN``
|
||||
A warning is emitted to the user.
|
||||
|
||||
``REFRESH``
|
||||
The cache is automatically refreshed, as if by :cmake-option:`--fresh`.
|
||||
Take care when setting this option, as all cache variables not specified in
|
||||
a configure preset or the current invocation of :manual:`cmake(1)` will be
|
||||
lost.
|
||||
@@ -0,0 +1,15 @@
|
||||
CMAKE_SYSTEM_ENVIRONMENT_ID
|
||||
---------------------------
|
||||
|
||||
.. versionadded:: 4.5
|
||||
|
||||
.. include:: include/ENV_VAR.rst
|
||||
|
||||
Externally-defined environment identifier that is cached. The value is not
|
||||
interpreted by :manual:`cmake(1)` and is a hint about the state of the
|
||||
environment during the first configure. When the value changes,
|
||||
:manual:`cmake(1)` by default emits a warning to the user indicating that the
|
||||
environment has changed and introspection results may be out of date.
|
||||
|
||||
The default warning behavior can be modified by setting
|
||||
:envvar:`CMAKE_SYSTEM_ENVIRONMENT_ACTION`.
|
||||
@@ -32,6 +32,8 @@ Environment Variables that Change Behavior
|
||||
/envvar/CMAKE_PROGRAM_PATH
|
||||
/envvar/CMAKE_TLS_VERIFY
|
||||
/envvar/CMAKE_TLS_VERSION
|
||||
/envvar/CMAKE_SYSTEM_ENVIRONMENT_ACTION
|
||||
/envvar/CMAKE_SYSTEM_ENVIRONMENT_ID
|
||||
/envvar/NO_COLOR
|
||||
/envvar/SSL_CERT_DIR
|
||||
/envvar/SSL_CERT_FILE
|
||||
|
||||
@@ -219,6 +219,11 @@ Options
|
||||
from any previous run will be removed. The download, update, and patch
|
||||
steps will therefore be forced to re-execute.
|
||||
|
||||
.. versionadded:: 4.5
|
||||
See the :envvar:`CMAKE_SYSTEM_ENVIRONMENT_ID` and
|
||||
:envvar:`CMAKE_SYSTEM_ENVIRONMENT_ACTION` environment variables for a
|
||||
mechanism to hint to :program:`cmake` when ``--fresh`` may be necessary.
|
||||
|
||||
.. option:: -L[A][H]
|
||||
|
||||
List non-advanced cached variables.
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
CMAKE_SYSTEM_ENVIRONMENT_ID
|
||||
---------------------------
|
||||
|
||||
* The :envvar:`CMAKE_SYSTEM_ENVIRONMENT_ID` environment variable was added to
|
||||
hint to :manual:`cmake(1)` when :cmake-option:`--fresh` may be necessary,
|
||||
along with :envvar:`CMAKE_SYSTEM_ENVIRONMENT_ACTION` to control what happens
|
||||
when :envvar:`CMAKE_SYSTEM_ENVIRONMENT_ID` changes.
|
||||
@@ -3033,6 +3033,68 @@ void cmake::InitializeInstrumentation()
|
||||
#endif
|
||||
}
|
||||
|
||||
int cmake::HandleDifferentSystemEnvironmentId(std::string envId,
|
||||
std::string cachedId)
|
||||
{
|
||||
enum class Action
|
||||
{
|
||||
Ignore,
|
||||
Warn,
|
||||
Refresh,
|
||||
} action = Action::Warn;
|
||||
static std::string const actionEnvName = "CMAKE_SYSTEM_ENVIRONMENT_ACTION";
|
||||
if (cmSystemTools::HasEnv(actionEnvName)) {
|
||||
std::string actionEnv;
|
||||
cmSystemTools::GetEnv(actionEnvName, actionEnv);
|
||||
if (actionEnv == "IGNORE") {
|
||||
action = Action::Ignore;
|
||||
} else if (actionEnv == "WARN") {
|
||||
action = Action::Warn;
|
||||
} else if (actionEnv == "REFRESH") {
|
||||
action = Action::Refresh;
|
||||
} else {
|
||||
this->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("Unsupported ", actionEnvName, " '", actionEnv, '\''));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
switch (action) {
|
||||
case Action::Ignore:
|
||||
break;
|
||||
case Action::Warn: {
|
||||
std::string msg = cmStrCat(
|
||||
"CMAKE_SYSTEM_ENVIRONMENT_ID: ", envId,
|
||||
"\nDoes not match the previous value: ", cachedId,
|
||||
"\nThe configure results are probably outdated. Consider running"
|
||||
" cmake with --fresh, removing the CMakeCache.txt file and"
|
||||
" CMakeFiles directory, or choosing a different binary"
|
||||
" directory.");
|
||||
this->IssueMessage(MessageType::WARNING, msg);
|
||||
break;
|
||||
}
|
||||
case Action::Refresh: {
|
||||
std::string msg =
|
||||
cmStrCat("CMAKE_SYSTEM_ENVIRONMENT_ID: ", envId,
|
||||
"\nDoes not match the previous value: ", cachedId,
|
||||
"\nThe cache will be refreshed automatically.");
|
||||
this->IssueMessage(MessageType::MESSAGE, msg);
|
||||
this->DeleteCache(this->GetHomeOutputDirectory());
|
||||
if (this->LoadCache() < 0) {
|
||||
cmSystemTools::Error(
|
||||
"Error executing cmake::LoadCache(). Aborting.\n");
|
||||
return -1;
|
||||
}
|
||||
this->AddCacheEntry(
|
||||
"CMAKE_SYSTEM_ENVIRONMENT_ID", envId,
|
||||
"Opaque identifier for the current system environment",
|
||||
cmStateEnums::INTERNAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// handle a command line invocation
|
||||
int cmake::Run(std::vector<std::string> const& args, bool noconfigure)
|
||||
{
|
||||
@@ -3079,6 +3141,24 @@ int cmake::Run(std::vector<std::string> const& args, bool noconfigure)
|
||||
cmSystemTools::Error("Error executing cmake::LoadCache(). Aborting.\n");
|
||||
return -1;
|
||||
}
|
||||
std::string const idKey = "CMAKE_SYSTEM_ENVIRONMENT_ID";
|
||||
cmValue cachedEnvId = this->State->GetInitializedCacheValue(idKey);
|
||||
std::string sysEnvId;
|
||||
cmSystemTools::GetEnv(idKey, sysEnvId);
|
||||
if (cachedEnvId) {
|
||||
if (sysEnvId != *cachedEnvId) {
|
||||
if (this->HandleDifferentSystemEnvironmentId(sysEnvId, *cachedEnvId) <
|
||||
0) {
|
||||
// Failed to LoadCache()
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this->AddCacheEntry(
|
||||
idKey, sysEnvId,
|
||||
"Opaque identifier for the current system environment",
|
||||
cmStateEnums::INTERNAL);
|
||||
}
|
||||
} else {
|
||||
if (this->FreshCache) {
|
||||
cmSystemTools::Error("--fresh allowed only when configuring a project");
|
||||
|
||||
@@ -712,6 +712,14 @@ protected:
|
||||
void RunCheckForUnusedVariables();
|
||||
int HandleDeleteCacheVariables(
|
||||
std::map<std::string, std::string> const& var);
|
||||
/**
|
||||
* Warn about different CMAKE_SYSTEM_ENVIRONMENT_ID, ignore, or refresh the
|
||||
* cache depending on CMAKE_SYSTEM_ENVIRONMENT_ACTION.
|
||||
*
|
||||
* @return 0 on success or -1 if LoadCache fails.
|
||||
*/
|
||||
int HandleDifferentSystemEnvironmentId(std::string envId,
|
||||
std::string cachedId);
|
||||
|
||||
using RegisteredGeneratorsVector =
|
||||
std::vector<std::unique_ptr<cmGlobalGeneratorFactory>>;
|
||||
|
||||
@@ -135,3 +135,52 @@ block()
|
||||
"-DCMAKE_TOOLCHAIN_FILE=foo.cmake"
|
||||
)
|
||||
endblock()
|
||||
|
||||
unset(ENV{CMAKE_SYSTEM_ENVIRONMENT_ID})
|
||||
unset(ENV{CMAKE_SYSTEM_ENVIRONMENT_ACTION})
|
||||
|
||||
block()
|
||||
set(ENV{CMAKE_SYSTEM_ENVIRONMENT_ID} original)
|
||||
run_cmake(SystemEnvironmentId)
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
|
||||
# Unchanged environment id should not emit a warning.
|
||||
set(RunCMake_TEST_VARIANT_DESCRIPTION Unchanged)
|
||||
run_cmake(SystemEnvironmentId)
|
||||
|
||||
set(ENV{CMAKE_SYSTEM_ENVIRONMENT_ID} different)
|
||||
|
||||
# Changed environment id should emit a warning by default.
|
||||
set(RunCMake_TEST_VARIANT_DESCRIPTION Changed)
|
||||
set(RunCMake-stderr-file SystemEnvironmentIdChanged-stderr.txt)
|
||||
run_cmake(SystemEnvironmentId)
|
||||
|
||||
# Changed environment id with IGNORE action should not emit a warning.
|
||||
set(RunCMake_TEST_VARIANT_DESCRIPTION ChangedIgnore)
|
||||
set(ENV{CMAKE_SYSTEM_ENVIRONMENT_ACTION} IGNORE)
|
||||
unset(RunCMake-stderr-file)
|
||||
run_cmake(SystemEnvironmentId)
|
||||
|
||||
# Changed environment id with WARN action should not emit a warning.
|
||||
set(RunCMake_TEST_VARIANT_DESCRIPTION ChangedWarn)
|
||||
set(ENV{CMAKE_SYSTEM_ENVIRONMENT_ACTION} WARN)
|
||||
set(RunCMake-stderr-file SystemEnvironmentIdChanged-stderr.txt)
|
||||
run_cmake(SystemEnvironmentId)
|
||||
|
||||
# Changed environment id with REFRESH action should refresh the cache.
|
||||
set(RunCMake_TEST_VARIANT_DESCRIPTION ChangedRefresh)
|
||||
set(ENV{CMAKE_SYSTEM_ENVIRONMENT_ACTION} REFRESH)
|
||||
set(RunCMake-stderr-file SystemEnvironmentIdChangedRefresh-stderr.txt)
|
||||
run_cmake(SystemEnvironmentId)
|
||||
|
||||
# Unrecognized CMAKE_SYSTEM_ENVIRONMENT_ACTION should error.
|
||||
set(RunCMake_TEST_VARIANT_DESCRIPTION InvalidAction)
|
||||
set(ENV{CMAKE_SYSTEM_ENVIRONMENT_ID} foo)
|
||||
set(ENV{CMAKE_SYSTEM_ENVIRONMENT_ACTION} bar)
|
||||
set(RunCMake_TEST_EXPECT_RESULT 1)
|
||||
set(RunCMake-stderr-file SystemEnvironmentIdInvalidAction-stderr.txt)
|
||||
run_cmake(SystemEnvironmentId)
|
||||
endblock()
|
||||
|
||||
unset(ENV{CMAKE_SYSTEM_ENVIRONMENT_ACTION})
|
||||
unset(ENV{CMAKE_SYSTEM_ENVIRONMENT_ID})
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
CMake Warning:
|
||||
CMAKE_SYSTEM_ENVIRONMENT_ID: different
|
||||
|
||||
Does not match the previous value: original
|
||||
|
||||
The configure results are probably outdated\. ?Consider running cmake with
|
||||
--fresh, removing the CMakeCache\.txt file and CMakeFiles directory, or
|
||||
choosing a different binary directory\.
|
||||
@@ -0,0 +1,6 @@
|
||||
CMake Warning:
|
||||
CMAKE_SYSTEM_ENVIRONMENT_ID: different
|
||||
|
||||
Does not match the previous value: original
|
||||
|
||||
The cache will be refreshed automatically\.
|
||||
@@ -0,0 +1,2 @@
|
||||
CMake Error:
|
||||
Unsupported CMAKE_SYSTEM_ENVIRONMENT_ACTION 'bar'
|
||||
Reference in New Issue
Block a user