diff options
-rw-r--r-- | Source/cmOptionCommand.cxx | 62 | ||||
-rw-r--r-- | Tests/RunCMake/option/CMP0077-SECOND-PASS.cmake | 14 | ||||
-rw-r--r-- | Tests/RunCMake/option/RunCMakeTest.cmake | 1 |
3 files changed, 51 insertions, 26 deletions
diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx index 4ab0e96..239cd00 100644 --- a/Source/cmOptionCommand.cxx +++ b/Source/cmOptionCommand.cxx @@ -28,32 +28,28 @@ bool cmOptionCommand::InitialPass(std::vector<std::string> const& args, } // 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; + bool checkAndWarn = false; + { + auto status = this->Makefile->GetPolicyStatus(cmPolicies::CMP0077); + const char* existsBeforeSet = + this->Makefile->GetStateSnapshot().GetDefinition(args[0]); + switch (status) { + case cmPolicies::WARN: + checkAndWarn = (existsBeforeSet != nullptr); + break; + 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 (existsBeforeSet) { + return true; + } + } break; + } } // See if a cache variable with this name already exists @@ -74,5 +70,19 @@ bool cmOptionCommand::InitialPass(std::vector<std::string> const& args, bool init = cmSystemTools::IsOn(initialValue.c_str()); this->Makefile->AddCacheDefinition(args[0], init ? "ON" : "OFF", args[1].c_str(), cmStateEnums::BOOL); + + if (checkAndWarn) { + const char* existsAfterSet = + this->Makefile->GetStateSnapshot().GetDefinition(args[0]); + if (!existsAfterSet) { + 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()); + } + } return true; } diff --git a/Tests/RunCMake/option/CMP0077-SECOND-PASS.cmake b/Tests/RunCMake/option/CMP0077-SECOND-PASS.cmake new file mode 100644 index 0000000..f62a853 --- /dev/null +++ b/Tests/RunCMake/option/CMP0077-SECOND-PASS.cmake @@ -0,0 +1,14 @@ + +#Verify that when both a cache and local version of a value exist that CMake +#doesn't produce a CMP0077 warning and that we get the expected values. +option(OPT_LOCAL_VAR "TEST_VAR" ON) +set(OPT_LOCAL_VAR FALSE) +option(OPT_LOCAL_VAR "TEST_VAR" ON) +if(OPT_LOCAL_VAR) + message(FATAL_ERROR "option improperly set a cache variable that already exists") +endif() + +get_property(_exists_in_cache CACHE OPT_LOCAL_VAR PROPERTY VALUE SET) +if(NOT _exists_in_cache) + message(FATAL_ERROR "value should exist in cache") +endif() diff --git a/Tests/RunCMake/option/RunCMakeTest.cmake b/Tests/RunCMake/option/RunCMakeTest.cmake index 0501624..979afa1 100644 --- a/Tests/RunCMake/option/RunCMakeTest.cmake +++ b/Tests/RunCMake/option/RunCMakeTest.cmake @@ -3,3 +3,4 @@ include(RunCMake) run_cmake(CMP0077-OLD) run_cmake(CMP0077-NEW) run_cmake(CMP0077-WARN) +run_cmake(CMP0077-SECOND-PASS) |