mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-05 21:31:08 -06:00
option: respect existing normal variable
Add policy CMP0077 to change this behavior in a compatible way.
This commit is contained in:
committed by
Brad King
parent
12e6f83319
commit
2a5f5c0e31
@@ -9,7 +9,9 @@ Provides an option that the user can optionally select.
|
|||||||
[initial value])
|
[initial value])
|
||||||
|
|
||||||
Provide an option for the user to select as ``ON`` or ``OFF``. If no
|
Provide an option for the user to select as ``ON`` or ``OFF``. If no
|
||||||
initial value is provided, ``OFF`` is used.
|
initial value is provided, ``OFF`` is used. If the option is already
|
||||||
|
set as a normal variable then the command does nothing
|
||||||
|
(see policy :policy:`CMP0077`).
|
||||||
|
|
||||||
If you have options that depend on the values of other options, see
|
If you have options that depend on the values of other options, see
|
||||||
the module help for :module:`CMakeDependentOption`.
|
the module help for :module:`CMakeDependentOption`.
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.13
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
|
CMP0077: option() honors normal variables. </policy/CMP0077>
|
||||||
CMP0076: target_sources() command converts relative paths to absolute. </policy/CMP0076>
|
CMP0076: target_sources() command converts relative paths to absolute. </policy/CMP0076>
|
||||||
|
|
||||||
Policies Introduced by CMake 3.12
|
Policies Introduced by CMake 3.12
|
||||||
|
|||||||
16
Help/policy/CMP0077.rst
Normal file
16
Help/policy/CMP0077.rst
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
CMP0077
|
||||||
|
-------
|
||||||
|
|
||||||
|
:command:`option` honors normal variables.
|
||||||
|
|
||||||
|
The ``OLD`` behavior for this policy is to clear any existing normal variables
|
||||||
|
with the same name. The ``NEW`` behavior for this policy is to not create
|
||||||
|
a cache entry or modify any existing normal variables if a normal variable
|
||||||
|
with the same name already exists.
|
||||||
|
|
||||||
|
This policy was introduced in CMake version 3.13. CMake version
|
||||||
|
|release| warns when the policy is not set and uses ``OLD`` behavior.
|
||||||
|
Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
|
||||||
|
explicitly.
|
||||||
|
|
||||||
|
.. include:: DEPRECATED.txt
|
||||||
5
Help/release/dev/option-normal-variable.rst
Normal file
5
Help/release/dev/option-normal-variable.rst
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
option-normal-variable
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
* The :command:`option` command now honors existing normal variables instead
|
||||||
|
of replacing them with a cache entry. See policy :policy:`CMP0077`.
|
||||||
@@ -2,11 +2,16 @@
|
|||||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||||
#include "cmOptionCommand.h"
|
#include "cmOptionCommand.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "cmAlgorithms.h"
|
#include "cmAlgorithms.h"
|
||||||
#include "cmMakefile.h"
|
#include "cmMakefile.h"
|
||||||
|
#include "cmPolicies.h"
|
||||||
#include "cmState.h"
|
#include "cmState.h"
|
||||||
|
#include "cmStateSnapshot.h"
|
||||||
#include "cmStateTypes.h"
|
#include "cmStateTypes.h"
|
||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
|
#include "cmake.h"
|
||||||
|
|
||||||
class cmExecutionStatus;
|
class cmExecutionStatus;
|
||||||
|
|
||||||
@@ -22,18 +27,47 @@ bool cmOptionCommand::InitialPass(std::vector<std::string> const& args,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string initialValue = "Off";
|
// Determine the state of the option policy
|
||||||
// Now check and see if the value has been stored in the cache
|
auto status = this->Makefile->GetPolicyStatus(cmPolicies::CMP0077);
|
||||||
// already, if so use that value and don't look for the program
|
const char* exists =
|
||||||
|
this->Makefile->GetStateSnapshot().GetDefinition(args[0]);
|
||||||
|
switch (status) {
|
||||||
|
case cmPolicies::WARN:
|
||||||
|
if (exists) {
|
||||||
|
std::ostringstream w;
|
||||||
|
w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0077)
|
||||||
|
<< "\n"
|
||||||
|
"For compatibility with older versions of CMake, option "
|
||||||
|
"is clearing the normal variable '"
|
||||||
|
<< args[0] << "'.";
|
||||||
|
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
|
||||||
|
}
|
||||||
|
case cmPolicies::OLD:
|
||||||
|
// OLD behavior does not warn.
|
||||||
|
break;
|
||||||
|
case cmPolicies::REQUIRED_ALWAYS:
|
||||||
|
case cmPolicies::REQUIRED_IF_USED:
|
||||||
|
case cmPolicies::NEW: {
|
||||||
|
// See if a local variable with this name already exists.
|
||||||
|
// If so we ignore the option command.
|
||||||
|
if (exists) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if a cache variable with this name already exists
|
||||||
|
// If so just make sure the doc state is correct
|
||||||
cmState* state = this->Makefile->GetState();
|
cmState* state = this->Makefile->GetState();
|
||||||
const char* existingValue = state->GetCacheEntryValue(args[0]);
|
const char* existingValue = state->GetCacheEntryValue(args[0]);
|
||||||
if (existingValue) {
|
if (existingValue &&
|
||||||
if (state->GetCacheEntryType(args[0]) != cmStateEnums::UNINITIALIZED) {
|
(state->GetCacheEntryType(args[0]) != cmStateEnums::UNINITIALIZED)) {
|
||||||
state->SetCacheEntryProperty(args[0], "HELPSTRING", args[1]);
|
state->SetCacheEntryProperty(args[0], "HELPSTRING", args[1]);
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
initialValue = existingValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Nothing in the cache so add it
|
||||||
|
std::string initialValue = existingValue ? existingValue : "Off";
|
||||||
if (args.size() == 3) {
|
if (args.size() == 3) {
|
||||||
initialValue = args[2];
|
initialValue = args[2];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,7 +226,9 @@ class cmMakefile;
|
|||||||
0, cmPolicies::WARN) \
|
0, cmPolicies::WARN) \
|
||||||
SELECT(POLICY, CMP0076, \
|
SELECT(POLICY, CMP0076, \
|
||||||
"target_sources() command converts relative paths to absolute.", 3, \
|
"target_sources() command converts relative paths to absolute.", 3, \
|
||||||
13, 0, cmPolicies::WARN)
|
13, 0, cmPolicies::WARN) \
|
||||||
|
SELECT(POLICY, CMP0077, "option() honors normal variables.", 3, 13, 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) \
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ add_CMakeOnly_test(TargetScope)
|
|||||||
|
|
||||||
add_CMakeOnly_test(find_library)
|
add_CMakeOnly_test(find_library)
|
||||||
add_CMakeOnly_test(find_path)
|
add_CMakeOnly_test(find_path)
|
||||||
add_CMakeOnly_test(option)
|
|
||||||
|
|
||||||
add_test(CMakeOnly.ProjectInclude ${CMAKE_CMAKE_COMMAND}
|
add_test(CMakeOnly.ProjectInclude ${CMAKE_CMAKE_COMMAND}
|
||||||
-DTEST=ProjectInclude
|
-DTEST=ProjectInclude
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
cmake_minimum_required (VERSION 2.8)
|
|
||||||
project(OptionTest NONE)
|
|
||||||
|
|
||||||
#Verify that normal variable take precedence over cache variables
|
|
||||||
option(OPT_LOCAL_VAR1 "TEST_VAR" ON)
|
|
||||||
set(OPT_LOCAL_VAR1 FALSE)
|
|
||||||
if(OPT_LOCAL_VAR1)
|
|
||||||
message(FATAL_ERROR "local variable didn't take precedence over cache variable")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#Verify that option overwrites existing normal variable
|
|
||||||
set(OPT_LOCAL_VAR2 FALSE)
|
|
||||||
option(OPT_LOCAL_VAR2 "TEST_VAR" ON)
|
|
||||||
if(NOT OPT_LOCAL_VAR2)
|
|
||||||
message(FATAL_ERROR "option failed to overwrite existing normal variable")
|
|
||||||
endif()
|
|
||||||
@@ -239,6 +239,7 @@ add_RunCMake_test(include_directories)
|
|||||||
add_RunCMake_test(include_guard)
|
add_RunCMake_test(include_guard)
|
||||||
add_RunCMake_test(list)
|
add_RunCMake_test(list)
|
||||||
add_RunCMake_test(message)
|
add_RunCMake_test(message)
|
||||||
|
add_RunCMake_test(option)
|
||||||
add_RunCMake_test(project -DCMake_TEST_RESOURCES=${CMake_TEST_RESOURCES})
|
add_RunCMake_test(project -DCMake_TEST_RESOURCES=${CMake_TEST_RESOURCES})
|
||||||
add_RunCMake_test(return)
|
add_RunCMake_test(return)
|
||||||
add_RunCMake_test(separate_arguments)
|
add_RunCMake_test(separate_arguments)
|
||||||
|
|||||||
14
Tests/RunCMake/option/CMP0077-NEW.cmake
Normal file
14
Tests/RunCMake/option/CMP0077-NEW.cmake
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
#Verify that option DOESN'T overwrite existing normal variable when the policy
|
||||||
|
#is set to NEW
|
||||||
|
cmake_policy(SET CMP0077 NEW)
|
||||||
|
set(OPT_LOCAL_VAR FALSE)
|
||||||
|
option(OPT_LOCAL_VAR "TEST_VAR" ON)
|
||||||
|
if(OPT_LOCAL_VAR)
|
||||||
|
message(FATAL_ERROR "option failed to overwrite existing normal variable")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
get_property(_exists_in_cache CACHE OPT_LOCAL_VAR PROPERTY VALUE SET)
|
||||||
|
if(_exists_in_cache)
|
||||||
|
message(FATAL_ERROR "value should not exist in cache as it was already a local variable")
|
||||||
|
endif()
|
||||||
9
Tests/RunCMake/option/CMP0077-OLD.cmake
Normal file
9
Tests/RunCMake/option/CMP0077-OLD.cmake
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
#Verify that option overwrites existing normal variable when the policy
|
||||||
|
#is set to OLD
|
||||||
|
cmake_policy(SET CMP0077 OLD)
|
||||||
|
set(OPT_LOCAL_VAR FALSE)
|
||||||
|
option(OPT_LOCAL_VAR "TEST_VAR" ON)
|
||||||
|
if(NOT OPT_LOCAL_VAR)
|
||||||
|
message(FATAL_ERROR "option failed to overwrite existing normal variable")
|
||||||
|
endif()
|
||||||
7
Tests/RunCMake/option/CMP0077-WARN-stderr.txt
Normal file
7
Tests/RunCMake/option/CMP0077-WARN-stderr.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
CMake Warning \(dev\) at CMP0077-WARN.cmake:5 \(option\):
|
||||||
|
Policy CMP0077 is not set: option\(\) honors normal variables. Run "cmake
|
||||||
|
--help-policy CMP0077" for policy details. Use the cmake_policy command to
|
||||||
|
set the policy and suppress this warning.
|
||||||
|
|
||||||
|
For compatibility with older versions of CMake, option is clearing the
|
||||||
|
normal variable 'OPT_LOCAL_VAR'.
|
||||||
5
Tests/RunCMake/option/CMP0077-WARN.cmake
Normal file
5
Tests/RunCMake/option/CMP0077-WARN.cmake
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
#Verify that option overwrites existing normal variable when the policy
|
||||||
|
#is set to OLD
|
||||||
|
set(OPT_LOCAL_VAR FALSE)
|
||||||
|
option(OPT_LOCAL_VAR "TEST_VAR" ON)
|
||||||
3
Tests/RunCMake/option/CMakeLists.txt
Normal file
3
Tests/RunCMake/option/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
project(${RunCMake_TEST} CXX)
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
||||||
5
Tests/RunCMake/option/RunCMakeTest.cmake
Normal file
5
Tests/RunCMake/option/RunCMakeTest.cmake
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
include(RunCMake)
|
||||||
|
|
||||||
|
run_cmake(CMP0077-OLD)
|
||||||
|
run_cmake(CMP0077-NEW)
|
||||||
|
run_cmake(CMP0077-WARN)
|
||||||
Reference in New Issue
Block a user