mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-16 05:26:58 +08:00
cmMarkAsAdvancedCommand: ignore variables which don't exist in the cache
Fixes: #18331
This commit is contained in:
@@ -22,3 +22,9 @@ If neither ``FORCE`` nor ``CLEAR`` is specified,
|
|||||||
new values will be marked as advanced, but if a
|
new values will be marked as advanced, but if a
|
||||||
variable already has an advanced/non-advanced state,
|
variable already has an advanced/non-advanced state,
|
||||||
it will not be changed.
|
it will not be changed.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Policy :policy:`CMP0102` affects the behavior of the ``mark_as_advanced``
|
||||||
|
call. When set to ``NEW``, variables passed to this command which are not
|
||||||
|
already in the cache are ignored. See policy :policy:`CMP0102`.
|
||||||
|
@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.17
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
|
CMP0102: mark_as_advanced() does nothing if a cache entry does not exist. </policy/CMP0102>
|
||||||
CMP0101: target_compile_options honors BEFORE keyword in all scopes. </policy/CMP0101>
|
CMP0101: target_compile_options honors BEFORE keyword in all scopes. </policy/CMP0101>
|
||||||
CMP0100: Let AUTOMOC and AUTOUIC process .hh header files. </policy/CMP0100>
|
CMP0100: Let AUTOMOC and AUTOUIC process .hh header files. </policy/CMP0100>
|
||||||
CMP0099: Link properties are transitive over private dependency on static libraries. </policy/CMP0099>
|
CMP0099: Link properties are transitive over private dependency on static libraries. </policy/CMP0099>
|
||||||
|
25
Help/policy/CMP0102.rst
Normal file
25
Help/policy/CMP0102.rst
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
CMP0102
|
||||||
|
-------
|
||||||
|
|
||||||
|
The :command:`mark_as_advanced` command no longer creates a cache entry if one
|
||||||
|
does not already exist.
|
||||||
|
|
||||||
|
In CMake 3.16 and below, if a variable was not defined at all or just defined
|
||||||
|
locally, the :command:`mark_as_advanced` command would create a new cache
|
||||||
|
entry with an ``UNINITIALIZED`` type and no value. When a :command:`find_path`
|
||||||
|
(or other similar ``find_`` command) would next run, it would find this
|
||||||
|
undefined cache entry and set it up with an empty string value. This process
|
||||||
|
would end up deleting the local variable in the process (due to the way the
|
||||||
|
cache works), effectively clearing any stored ``find_`` results that were only
|
||||||
|
available in the local scope.
|
||||||
|
|
||||||
|
The ``OLD`` behavior for this policy is to create the empty cache definition.
|
||||||
|
The ``NEW`` behavior of this policy is to ignore variables which do not
|
||||||
|
already exist in the cache.
|
||||||
|
|
||||||
|
This policy was introduced in CMake version 3.17. Use the
|
||||||
|
:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
|
||||||
|
Unlike many policies, CMake version |release| does *not* warn
|
||||||
|
when this policy is not set and simply uses ``OLD`` behavior.
|
||||||
|
|
||||||
|
.. include:: DEPRECATED.txt
|
@@ -23,6 +23,8 @@ warn by default:
|
|||||||
policy :policy:`CMP0082`.
|
policy :policy:`CMP0082`.
|
||||||
* ``CMAKE_POLICY_WARNING_CMP0089`` controls the warning for
|
* ``CMAKE_POLICY_WARNING_CMP0089`` controls the warning for
|
||||||
policy :policy:`CMP0089`.
|
policy :policy:`CMP0089`.
|
||||||
|
* ``CMAKE_POLICY_WARNING_CMP0102`` controls the warning for
|
||||||
|
policy :policy:`CMP0102`.
|
||||||
|
|
||||||
This variable should not be set by a project in CMake code. Project
|
This variable should not be set by a project in CMake code. Project
|
||||||
developers running CMake may set this variable in their cache to
|
developers running CMake may set this variable in their cache to
|
||||||
|
@@ -4,8 +4,11 @@
|
|||||||
|
|
||||||
#include "cmExecutionStatus.h"
|
#include "cmExecutionStatus.h"
|
||||||
#include "cmMakefile.h"
|
#include "cmMakefile.h"
|
||||||
|
#include "cmMessageType.h"
|
||||||
|
#include "cmPolicies.h"
|
||||||
#include "cmState.h"
|
#include "cmState.h"
|
||||||
#include "cmStateTypes.h"
|
#include "cmStateTypes.h"
|
||||||
|
#include "cmStringAlgorithms.h"
|
||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
#include "cmake.h"
|
#include "cmake.h"
|
||||||
|
|
||||||
@@ -28,14 +31,63 @@ bool cmMarkAsAdvancedCommand(std::vector<std::string> const& args,
|
|||||||
}
|
}
|
||||||
i = 1;
|
i = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmMakefile& mf = status.GetMakefile();
|
||||||
|
cmState* state = mf.GetState();
|
||||||
|
|
||||||
for (; i < args.size(); ++i) {
|
for (; i < args.size(); ++i) {
|
||||||
std::string const& variable = args[i];
|
std::string const& variable = args[i];
|
||||||
cmState* state = status.GetMakefile().GetState();
|
|
||||||
if (!state->GetCacheEntryValue(variable)) {
|
bool issueMessage = false;
|
||||||
status.GetMakefile().GetCMakeInstance()->AddCacheEntry(
|
bool oldBehavior = false;
|
||||||
variable, nullptr, nullptr, cmStateEnums::UNINITIALIZED);
|
bool ignoreVariable = false;
|
||||||
overwrite = true;
|
switch (mf.GetPolicyStatus(cmPolicies::CMP0102)) {
|
||||||
|
case cmPolicies::WARN:
|
||||||
|
if (mf.PolicyOptionalWarningEnabled("CMAKE_POLICY_WARNING_CMP0102")) {
|
||||||
|
if (!state->GetCacheEntryValue(variable)) {
|
||||||
|
issueMessage = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CM_FALLTHROUGH;
|
||||||
|
case cmPolicies::OLD:
|
||||||
|
oldBehavior = true;
|
||||||
|
break;
|
||||||
|
case cmPolicies::NEW:
|
||||||
|
case cmPolicies::REQUIRED_IF_USED:
|
||||||
|
case cmPolicies::REQUIRED_ALWAYS:
|
||||||
|
if (!state->GetCacheEntryValue(variable)) {
|
||||||
|
ignoreVariable = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// First see if we should issue a message about CMP0102
|
||||||
|
if (issueMessage) {
|
||||||
|
std::string err = cmStrCat(
|
||||||
|
"Policy CMP0102 is not set: The variable named \"", variable,
|
||||||
|
"\" is not in the cache. This results in an empty cache entry which "
|
||||||
|
"is no longer created when policy CMP0102 is set to NEW. Run \"cmake "
|
||||||
|
"--help-policy CMP0102\" for policy details. Use the cmake_policy "
|
||||||
|
"command to set the policy and suppress this warning.");
|
||||||
|
mf.IssueMessage(MessageType::AUTHOR_WARNING, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's not in the cache and we're using the new behavior, nothing to
|
||||||
|
// see here.
|
||||||
|
if (ignoreVariable) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we want the old behavior of making a dummy cache entry.
|
||||||
|
if (oldBehavior) {
|
||||||
|
if (!state->GetCacheEntryValue(variable)) {
|
||||||
|
status.GetMakefile().GetCMakeInstance()->AddCacheEntry(
|
||||||
|
variable, nullptr, nullptr, cmStateEnums::UNINITIALIZED);
|
||||||
|
overwrite = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a cache entry to do this.
|
||||||
if (!state->GetCacheEntryValue(variable)) {
|
if (!state->GetCacheEntryValue(variable)) {
|
||||||
cmSystemTools::Error("This should never happen...");
|
cmSystemTools::Error("This should never happen...");
|
||||||
return false;
|
return false;
|
||||||
|
@@ -302,7 +302,10 @@ class cmMakefile;
|
|||||||
17, 0, cmPolicies::WARN) \
|
17, 0, cmPolicies::WARN) \
|
||||||
SELECT(POLICY, CMP0101, \
|
SELECT(POLICY, CMP0101, \
|
||||||
"target_compile_options honors BEFORE keyword in all scopes.", 3, \
|
"target_compile_options honors BEFORE keyword in all scopes.", 3, \
|
||||||
17, 0, cmPolicies::WARN)
|
17, 0, cmPolicies::WARN) \
|
||||||
|
SELECT(POLICY, CMP0102, \
|
||||||
|
"mark_as_advanced() does nothing if a cache entry does not exist.", \
|
||||||
|
3, 17, 0, cmPolicies::WARN)
|
||||||
|
|
||||||
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
|
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
|
||||||
#define CM_FOR_EACH_POLICY_ID(POLICY) \
|
#define CM_FOR_EACH_POLICY_ID(POLICY) \
|
||||||
|
2
Tests/RunCMake/CMP0102/CMP0102-Common.cmake
Normal file
2
Tests/RunCMake/CMP0102/CMP0102-Common.cmake
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
mark_as_advanced(CMP0102_TEST_VARIABLE)
|
13
Tests/RunCMake/CMP0102/CMP0102-NEW.cmake
Normal file
13
Tests/RunCMake/CMP0102/CMP0102-NEW.cmake
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
cmake_policy(SET CMP0102 NEW)
|
||||||
|
|
||||||
|
include (CMP0102-Common.cmake)
|
||||||
|
get_property(is_type_set CACHE CMP0102_TEST_VARIABLE
|
||||||
|
PROPERTY TYPE SET)
|
||||||
|
if (is_type_set)
|
||||||
|
get_property(type CACHE CMP0102_TEST_VARIABLE
|
||||||
|
PROPERTY TYPE)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"There is a cache entry for an undefined variable after "
|
||||||
|
"`mark_as_advanced`.")
|
||||||
|
endif ()
|
18
Tests/RunCMake/CMP0102/CMP0102-OLD.cmake
Normal file
18
Tests/RunCMake/CMP0102/CMP0102-OLD.cmake
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
cmake_policy(SET CMP0102 OLD)
|
||||||
|
|
||||||
|
include (CMP0102-Common.cmake)
|
||||||
|
get_property(is_type_set CACHE CMP0102_TEST_VARIABLE
|
||||||
|
PROPERTY TYPE SET)
|
||||||
|
if (NOT is_type_set)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"There is a cache entry for an undefined variable after "
|
||||||
|
"`mark_as_advanced`.")
|
||||||
|
endif ()
|
||||||
|
get_property(type CACHE CMP0102_TEST_VARIABLE
|
||||||
|
PROPERTY TYPE)
|
||||||
|
if (NOT type STREQUAL "UNINITIALIZED")
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"The cache type for CMP0102_TEST_VARIABLE is not "
|
||||||
|
"UNINITIALIZED")
|
||||||
|
endif ()
|
16
Tests/RunCMake/CMP0102/CMP0102-WARN-Default.cmake
Normal file
16
Tests/RunCMake/CMP0102/CMP0102-WARN-Default.cmake
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
include (CMP0102-Common.cmake)
|
||||||
|
get_property(is_type_set CACHE CMP0102_TEST_VARIABLE
|
||||||
|
PROPERTY TYPE SET)
|
||||||
|
if (NOT is_type_set)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"There is a cache entry for an undefined variable after "
|
||||||
|
"`mark_as_advanced`.")
|
||||||
|
endif ()
|
||||||
|
get_property(type CACHE CMP0102_TEST_VARIABLE
|
||||||
|
PROPERTY TYPE)
|
||||||
|
if (NOT type STREQUAL "UNINITIALIZED")
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"The cache type for CMP0102_TEST_VARIABLE is not "
|
||||||
|
"UNINITIALIZED")
|
||||||
|
endif ()
|
10
Tests/RunCMake/CMP0102/CMP0102-WARN-stderr.txt
Normal file
10
Tests/RunCMake/CMP0102/CMP0102-WARN-stderr.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
CMake Warning \(dev\) at CMP0102-Common.cmake:2 \(mark_as_advanced\):
|
||||||
|
Policy CMP0102 is not set: The variable named "CMP0102_TEST_VARIABLE" is
|
||||||
|
not in the cache. This results in an empty cache entry which is no longer
|
||||||
|
created when policy CMP0102 is set to NEW. Run "cmake --help-policy
|
||||||
|
CMP0102" for policy details. Use the cmake_policy command to set the
|
||||||
|
policy and suppress this warning.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMP0102-WARN.cmake:4 \(include\)
|
||||||
|
CMakeLists.txt:3 \(include\)
|
||||||
|
This warning is for project developers. Use -Wno-dev to suppress it.
|
18
Tests/RunCMake/CMP0102/CMP0102-WARN.cmake
Normal file
18
Tests/RunCMake/CMP0102/CMP0102-WARN.cmake
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
set(CMAKE_POLICY_WARNING_CMP0102 1)
|
||||||
|
|
||||||
|
include (CMP0102-Common.cmake)
|
||||||
|
get_property(is_type_set CACHE CMP0102_TEST_VARIABLE
|
||||||
|
PROPERTY TYPE SET)
|
||||||
|
if (NOT is_type_set)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"There is a cache entry for an undefined variable after "
|
||||||
|
"`mark_as_advanced`.")
|
||||||
|
endif ()
|
||||||
|
get_property(type CACHE CMP0102_TEST_VARIABLE
|
||||||
|
PROPERTY TYPE)
|
||||||
|
if (NOT type STREQUAL "UNINITIALIZED")
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"The cache type for CMP0102_TEST_VARIABLE is not "
|
||||||
|
"UNINITIALIZED")
|
||||||
|
endif ()
|
3
Tests/RunCMake/CMP0102/CMakeLists.txt
Normal file
3
Tests/RunCMake/CMP0102/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.1)
|
||||||
|
project(${RunCMake_TEST} NONE)
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
6
Tests/RunCMake/CMP0102/RunCMakeTest.cmake
Normal file
6
Tests/RunCMake/CMP0102/RunCMakeTest.cmake
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
include(RunCMake)
|
||||||
|
|
||||||
|
run_cmake(CMP0102-OLD)
|
||||||
|
run_cmake(CMP0102-NEW)
|
||||||
|
run_cmake(CMP0102-WARN)
|
||||||
|
run_cmake(CMP0102-WARN-Default)
|
@@ -115,6 +115,7 @@ if(CMAKE_SYSTEM_NAME MATCHES Darwin AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
|
|||||||
endif()
|
endif()
|
||||||
add_RunCMake_test(CMP0069)
|
add_RunCMake_test(CMP0069)
|
||||||
add_RunCMake_test(CMP0081)
|
add_RunCMake_test(CMP0081)
|
||||||
|
add_RunCMake_test(CMP0102)
|
||||||
|
|
||||||
# The test for Policy 65 requires the use of the
|
# The test for Policy 65 requires the use of the
|
||||||
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
|
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
|
||||||
|
Reference in New Issue
Block a user