/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCMakePolicyCommand.h" #include #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" #include "cmState.h" #include "cmStateTypes.h" class cmExecutionStatus; // cmCMakePolicyCommand bool cmCMakePolicyCommand::InitialPass(std::vector const& args, cmExecutionStatus&) { if (args.empty()) { this->SetError("requires at least one argument."); return false; } if (args[0] == "SET") { return this->HandleSetMode(args); } if (args[0] == "GET") { return this->HandleGetMode(args); } if (args[0] == "PUSH") { if (args.size() > 1) { this->SetError("PUSH may not be given additional arguments."); return false; } this->Makefile->PushPolicy(); return true; } if (args[0] == "POP") { if (args.size() > 1) { this->SetError("POP may not be given additional arguments."); return false; } this->Makefile->PopPolicy(); return true; } if (args[0] == "VERSION") { return this->HandleVersionMode(args); } if (args[0] == "GET_WARNING") { return this->HandleGetWarningMode(args); } std::ostringstream e; e << "given unknown first argument \"" << args[0] << "\""; this->SetError(e.str()); return false; } bool cmCMakePolicyCommand::HandleSetMode(std::vector const& args) { if (args.size() != 3) { this->SetError("SET must be given exactly 2 additional arguments."); return false; } cmPolicies::PolicyStatus status; if (args[2] == "OLD") { status = cmPolicies::OLD; } else if (args[2] == "NEW") { status = cmPolicies::NEW; } else { std::ostringstream e; e << "SET given unrecognized policy status \"" << args[2] << "\""; this->SetError(e.str()); return false; } if (!this->Makefile->SetPolicy(args[1].c_str(), status)) { this->SetError("SET failed to set policy."); return false; } if (args[1] == "CMP0001" && (status == cmPolicies::WARN || status == cmPolicies::OLD)) { if (!(this->Makefile->GetState()->GetInitializedCacheValue( "CMAKE_BACKWARDS_COMPATIBILITY"))) { // Set it to 2.4 because that is the last version where the // variable had meaning. this->Makefile->AddCacheDefinition( "CMAKE_BACKWARDS_COMPATIBILITY", "2.4", "For backwards compatibility, what version of CMake " "commands and " "syntax should this version of CMake try to support.", cmStateEnums::STRING); } } return true; } bool cmCMakePolicyCommand::HandleGetMode(std::vector const& args) { bool parent_scope = false; if (args.size() == 4 && args[3] == "PARENT_SCOPE") { // Undocumented PARENT_SCOPE option for use within CMake. parent_scope = true; } else if (args.size() != 3) { this->SetError("GET must be given exactly 2 additional arguments."); return false; } // Get arguments. std::string const& id = args[1]; std::string const& var = args[2]; // Lookup the policy number. cmPolicies::PolicyID pid; if (!cmPolicies::GetPolicyID(id.c_str(), pid)) { std::ostringstream e; e << "GET given policy \"" << id << "\" which is not known to this " << "version of CMake."; this->SetError(e.str()); return false; } // Lookup the policy setting. cmPolicies::PolicyStatus status = this->Makefile->GetPolicyStatus(pid, parent_scope); switch (status) { case cmPolicies::OLD: // Report that the policy is set to OLD. this->Makefile->AddDefinition(var, "OLD"); break; case cmPolicies::WARN: // Report that the policy is not set. this->Makefile->AddDefinition(var, ""); break; case cmPolicies::NEW: // Report that the policy is set to NEW. this->Makefile->AddDefinition(var, "NEW"); break; case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: // The policy is required to be set before anything needs it. { std::ostringstream e; e << cmPolicies::GetRequiredPolicyError(pid) << "\n" << "The call to cmake_policy(GET " << id << " ...) at which this " << "error appears requests the policy, and this version of CMake " << "requires that the policy be set to NEW before it is checked."; this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); } } return true; } bool cmCMakePolicyCommand::HandleVersionMode( std::vector const& args) { if (args.size() <= 1) { this->SetError("VERSION not given an argument"); return false; } if (args.size() >= 3) { this->SetError("VERSION given too many arguments"); return false; } std::string const& version_string = args[1]; // Separate the version and any trailing ... component. std::string::size_type const dd = version_string.find("..."); std::string const version_min = version_string.substr(0, dd); std::string const version_max = dd != std::string::npos ? version_string.substr(dd + 3, std::string::npos) : std::string(); if (dd != std::string::npos && (version_min.empty() || version_max.empty())) { std::ostringstream e; e << "VERSION \"" << version_string << R"(" does not have a version on both sides of "...".)"; this->SetError(e.str()); return false; } this->Makefile->SetPolicyVersion(version_min, version_max); return true; } bool cmCMakePolicyCommand::HandleGetWarningMode( std::vector const& args) { if (args.size() != 3) { this->SetError( "GET_WARNING must be given exactly 2 additional arguments."); return false; } // Get arguments. std::string const& id = args[1]; std::string const& var = args[2]; // Lookup the policy number. cmPolicies::PolicyID pid; if (!cmPolicies::GetPolicyID(id.c_str(), pid)) { std::ostringstream e; e << "GET_WARNING given policy \"" << id << "\" which is not known to this version of CMake."; this->SetError(e.str()); return false; } // Lookup the policy warning. this->Makefile->AddDefinition(var, cmPolicies::GetPolicyWarning(pid)); return true; }