diff options
-rw-r--r-- | Help/command/option.rst | 4 | ||||
-rw-r--r-- | Help/manual/cmake-policies.7.rst | 1 | ||||
-rw-r--r-- | Help/policy/CMP0077.rst | 16 | ||||
-rw-r--r-- | Help/release/dev/option-normal-variable.rst | 5 | ||||
-rw-r--r-- | Source/cmOptionCommand.cxx | 66 | ||||
-rw-r--r-- | Source/cmPolicies.h | 4 | ||||
-rw-r--r-- | Tests/RunCMake/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/option/CMP0077-NEW.cmake | 14 | ||||
-rw-r--r-- | Tests/RunCMake/option/CMP0077-OLD.cmake | 9 | ||||
-rw-r--r-- | Tests/RunCMake/option/CMP0077-WARN-stderr.txt | 7 | ||||
-rw-r--r-- | Tests/RunCMake/option/CMP0077-WARN.cmake | 5 | ||||
-rw-r--r-- | Tests/RunCMake/option/CMakeLists.txt | 3 | ||||
-rw-r--r-- | Tests/RunCMake/option/RunCMakeTest.cmake | 5 |
13 files changed, 116 insertions, 24 deletions
diff --git a/Help/command/option.rst b/Help/command/option.rst index 91cd0a7..4fabb87 100644 --- a/Help/command/option.rst +++ b/Help/command/option.rst @@ -9,7 +9,9 @@ Provides an option that the user can optionally select. [initial value]) 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 the module help for :module:`CMakeDependentOption`. diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 6179a7c..b2eeb3a 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -57,6 +57,7 @@ Policies Introduced by CMake 3.13 .. toctree:: :maxdepth: 1 + CMP0077: option() honors normal variables. </policy/CMP0077> CMP0076: target_sources() command converts relative paths to absolute. </policy/CMP0076> Policies Introduced by CMake 3.12 diff --git a/Help/policy/CMP0077.rst b/Help/policy/CMP0077.rst new file mode 100644 index 0000000..8efe198 --- /dev/null +++ b/Help/policy/CMP0077.rst @@ -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 diff --git a/Help/release/dev/option-normal-variable.rst b/Help/release/dev/option-normal-variable.rst new file mode 100644 index 0000000..19b9a64 --- /dev/null +++ b/Help/release/dev/option-normal-variable.rst @@ -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`. diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx index 00a2d2b..4ab0e96 100644 --- a/Source/cmOptionCommand.cxx +++ b/Source/cmOptionCommand.cxx @@ -2,11 +2,16 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmOptionCommand.h" +#include <sstream> + #include "cmAlgorithms.h" #include "cmMakefile.h" +#include "cmPolicies.h" #include "cmState.h" +#include "cmStateSnapshot.h" #include "cmStateTypes.h" #include "cmSystemTools.h" +#include "cmake.h" class cmExecutionStatus; @@ -14,19 +19,7 @@ class cmExecutionStatus; bool cmOptionCommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus&) { - bool argError = false; - if (args.size() < 2) { - argError = true; - } - // for VTK 4.0 we have to support the option command with more than 3 - // arguments if CMAKE_MINIMUM_REQUIRED_VERSION is not defined, if - // CMAKE_MINIMUM_REQUIRED_VERSION is defined, then we can have stricter - // checking. - if (this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) { - if (args.size() > 3) { - argError = true; - } - } + const bool argError = (args.size() < 2) || (args.size() > 3); if (argError) { std::string m = "called with incorrect number of arguments: "; m += cmJoin(args, " "); @@ -34,18 +27,47 @@ bool cmOptionCommand::InitialPass(std::vector<std::string> const& args, return false; } - std::string initialValue = "Off"; - // Now check and see if the value has been stored in the cache - // already, if so use that value and don't look for the program + // Determine the state of the option policy + auto status = this->Makefile->GetPolicyStatus(cmPolicies::CMP0077); + 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(); const char* existingValue = state->GetCacheEntryValue(args[0]); - if (existingValue) { - if (state->GetCacheEntryType(args[0]) != cmStateEnums::UNINITIALIZED) { - state->SetCacheEntryProperty(args[0], "HELPSTRING", args[1]); - return true; - } - initialValue = existingValue; + if (existingValue && + (state->GetCacheEntryType(args[0]) != cmStateEnums::UNINITIALIZED)) { + state->SetCacheEntryProperty(args[0], "HELPSTRING", args[1]); + return true; } + + // Nothing in the cache so add it + std::string initialValue = existingValue ? existingValue : "Off"; if (args.size() == 3) { initialValue = args[2]; } diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 1732ad6..d0d9307 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -226,7 +226,9 @@ class cmMakefile; 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0076, \ "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_FOR_EACH_POLICY_ID(POLICY) \ diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index c211f99..97c3178 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -240,6 +240,7 @@ add_RunCMake_test(include_guard) add_RunCMake_test(list) add_RunCMake_test(math) add_RunCMake_test(message) +add_RunCMake_test(option) add_RunCMake_test(project -DCMake_TEST_RESOURCES=${CMake_TEST_RESOURCES}) add_RunCMake_test(return) add_RunCMake_test(separate_arguments) diff --git a/Tests/RunCMake/option/CMP0077-NEW.cmake b/Tests/RunCMake/option/CMP0077-NEW.cmake new file mode 100644 index 0000000..d4c518b --- /dev/null +++ b/Tests/RunCMake/option/CMP0077-NEW.cmake @@ -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() diff --git a/Tests/RunCMake/option/CMP0077-OLD.cmake b/Tests/RunCMake/option/CMP0077-OLD.cmake new file mode 100644 index 0000000..4c52d4b --- /dev/null +++ b/Tests/RunCMake/option/CMP0077-OLD.cmake @@ -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() diff --git a/Tests/RunCMake/option/CMP0077-WARN-stderr.txt b/Tests/RunCMake/option/CMP0077-WARN-stderr.txt new file mode 100644 index 0000000..0d02ffb --- /dev/null +++ b/Tests/RunCMake/option/CMP0077-WARN-stderr.txt @@ -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'. diff --git a/Tests/RunCMake/option/CMP0077-WARN.cmake b/Tests/RunCMake/option/CMP0077-WARN.cmake new file mode 100644 index 0000000..7f99456 --- /dev/null +++ b/Tests/RunCMake/option/CMP0077-WARN.cmake @@ -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) diff --git a/Tests/RunCMake/option/CMakeLists.txt b/Tests/RunCMake/option/CMakeLists.txt new file mode 100644 index 0000000..11dc49a --- /dev/null +++ b/Tests/RunCMake/option/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.12) +project(${RunCMake_TEST} CXX) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/option/RunCMakeTest.cmake b/Tests/RunCMake/option/RunCMakeTest.cmake new file mode 100644 index 0000000..0501624 --- /dev/null +++ b/Tests/RunCMake/option/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(CMP0077-OLD) +run_cmake(CMP0077-NEW) +run_cmake(CMP0077-WARN) |