/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmOptionCommand.h" #include #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" #include "cmState.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; // cmOptionCommand bool cmOptionCommand::InitialPass(std::vector const& args, cmExecutionStatus&) { const bool argError = (args.size() < 2) || (args.size() > 3); if (argError) { std::string m = "called with incorrect number of arguments: "; m += cmJoin(args, " "); this->SetError(m); return false; } // Determine the state of the option policy bool checkAndWarn = false; { auto status = this->Makefile->GetPolicyStatus(cmPolicies::CMP0077); const auto* 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 // If so just make sure the doc state is correct cmState* state = this->Makefile->GetState(); const char* existingValue = state->GetCacheEntryValue(args[0]); 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]; } bool init = cmSystemTools::IsOn(initialValue); this->Makefile->AddCacheDefinition(args[0], init ? "ON" : "OFF", args[1].c_str(), cmStateEnums::BOOL); if (checkAndWarn) { const auto* 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(MessageType::AUTHOR_WARNING, w.str()); } } return true; }