option: No CMP077 warnings when both cache and local variable exists

Previously we would warn when the local and cache version of a variable
exists, but this use case doesn't need a warning as it maintains backwards
compatibility.
This commit is contained in:
Robert Maynard
2018-07-10 13:56:15 -04:00
parent 2a5f5c0e31
commit f8a7cf85ad
3 changed files with 51 additions and 26 deletions

View File

@@ -28,32 +28,28 @@ bool cmOptionCommand::InitialPass(std::vector<std::string> const& args,
} }
// Determine the state of the option policy // Determine the state of the option policy
auto status = this->Makefile->GetPolicyStatus(cmPolicies::CMP0077); bool checkAndWarn = false;
const char* exists = {
this->Makefile->GetStateSnapshot().GetDefinition(args[0]); auto status = this->Makefile->GetPolicyStatus(cmPolicies::CMP0077);
switch (status) { const char* existsBeforeSet =
case cmPolicies::WARN: this->Makefile->GetStateSnapshot().GetDefinition(args[0]);
if (exists) { switch (status) {
std::ostringstream w; case cmPolicies::WARN:
w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0077) checkAndWarn = (existsBeforeSet != nullptr);
<< "\n" break;
"For compatibility with older versions of CMake, option " case cmPolicies::OLD:
"is clearing the normal variable '" // OLD behavior does not warn.
<< args[0] << "'."; break;
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); case cmPolicies::REQUIRED_ALWAYS:
} case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::OLD: case cmPolicies::NEW: {
// OLD behavior does not warn. // See if a local variable with this name already exists.
break; // If so we ignore the option command.
case cmPolicies::REQUIRED_ALWAYS: if (existsBeforeSet) {
case cmPolicies::REQUIRED_IF_USED: return true;
case cmPolicies::NEW: { }
// See if a local variable with this name already exists. } break;
// If so we ignore the option command. }
if (exists) {
return true;
}
} break;
} }
// See if a cache variable with this name already exists // 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()); bool init = cmSystemTools::IsOn(initialValue.c_str());
this->Makefile->AddCacheDefinition(args[0], init ? "ON" : "OFF", this->Makefile->AddCacheDefinition(args[0], init ? "ON" : "OFF",
args[1].c_str(), cmStateEnums::BOOL); 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; return true;
} }

View File

@@ -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()

View File

@@ -3,3 +3,4 @@ include(RunCMake)
run_cmake(CMP0077-OLD) run_cmake(CMP0077-OLD)
run_cmake(CMP0077-NEW) run_cmake(CMP0077-NEW)
run_cmake(CMP0077-WARN) run_cmake(CMP0077-WARN)
run_cmake(CMP0077-SECOND-PASS)