Browse Source

ENH: Add cmake_policy(GET) command mode

It is likely that projects or CMake modules in the future will need to
check the value of a policy setting.  For example, if we add a policy
that affects the results of FindXYZ.cmake modules, the module code will
need to be able to check the policy.
Brad King 17 years ago
parent
commit
7f7068e9d4

+ 61 - 0
Source/cmCMakePolicyCommand.cxx

@@ -32,6 +32,10 @@ bool cmCMakePolicyCommand
     {
     return this->HandleSetMode(args);
     }
+  else if(args[0] == "GET")
+    {
+    return this->HandleGetMode(args);
+    }
   else if(args[0] == "PUSH")
     {
     if(args.size() > 1)
@@ -103,6 +107,63 @@ bool cmCMakePolicyCommand::HandleSetMode(std::vector<std::string> const& args)
   return true;
 }
 
+//----------------------------------------------------------------------------
+bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args)
+{
+  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(!this->Makefile->GetPolicies()->GetPolicyID(id.c_str(), pid))
+    {
+    cmOStringStream e;
+    e << "GET given policy \"" << id << "\" which is not known to this "
+      << "version of CMake.";
+    this->SetError(e.str().c_str());
+    return false;
+    }
+
+  // Lookup the policy setting.
+  cmPolicies::PolicyStatus status = this->Makefile->GetPolicyStatus(pid);
+  switch (status)
+    {
+    case cmPolicies::OLD:
+      // Report that the policy is set to OLD.
+      this->Makefile->AddDefinition(var.c_str(), "OLD");
+      break;
+    case cmPolicies::WARN:
+      // Report that the policy is not set.
+      this->Makefile->AddDefinition(var.c_str(), "");
+      break;
+    case cmPolicies::NEW:
+      // Report that the policy is set to NEW.
+      this->Makefile->AddDefinition(var.c_str(), "NEW");
+      break;
+    case cmPolicies::REQUIRED_IF_USED:
+    case cmPolicies::REQUIRED_ALWAYS:
+      // The policy is required to be set before anything needs it.
+      {
+      cmOStringStream e;
+      e << this->Makefile->GetPolicies()->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(cmake::FATAL_ERROR, e.str());
+      }
+    }
+
+  return true;
+}
+
 //----------------------------------------------------------------------------
 bool
 cmCMakePolicyCommand::HandleVersionMode(std::vector<std::string> const& args)

+ 6 - 0
Source/cmCMakePolicyCommand.h

@@ -108,6 +108,11 @@ public:
       "Alternatively one may fix the project to work with the new behavior "
       "and set the policy state to NEW."
       "\n"
+      "  cmake_policy(GET CMP<NNNN> <variable>)\n"
+      "Check whether a given policy is set to OLD or NEW behavior.  "
+      "The output variable value will be \"OLD\" or \"NEW\" if the "
+      "policy is set, and empty otherwise."
+      "\n"
       "  cmake_policy(PUSH)\n"
       "  cmake_policy(POP)\n"
       "Push and pop the current policy setting state on a stack.  "
@@ -123,6 +128,7 @@ public:
   cmTypeMacro(cmCMakePolicyCommand, cmCommand);
 private:
   bool HandleSetMode(std::vector<std::string> const& args);
+  bool HandleGetMode(std::vector<std::string> const& args);
   bool HandleVersionMode(std::vector<std::string> const& args);
 };
 

+ 5 - 0
Tests/Complex/CMakeLists.txt

@@ -7,6 +7,11 @@ PROJECT (Complex)
 # Try setting a new policy.  The IF test is for coverage.
 IF(POLICY CMP0003)
   CMAKE_POLICY(SET CMP0003 NEW)
+
+  CMAKE_POLICY(GET CMP0003 P3)
+  IF(NOT "${P3}" STREQUAL "NEW")
+    MESSAGE(FATAL_ERROR "CMAKE_POLICY(GET) did not report NEW!")
+  ENDIF(NOT "${P3}" STREQUAL "NEW")
 ENDIF(POLICY CMP0003)
 
 # Choose whether to test CMakeLib.

+ 5 - 0
Tests/ComplexOneConfig/CMakeLists.txt

@@ -7,6 +7,11 @@ PROJECT (Complex)
 # Try setting a new policy.  The IF test is for coverage.
 IF(POLICY CMP0003)
   CMAKE_POLICY(SET CMP0003 NEW)
+
+  CMAKE_POLICY(GET CMP0003 P3)
+  IF(NOT "${P3}" STREQUAL "NEW")
+    MESSAGE(FATAL_ERROR "CMAKE_POLICY(GET) did not report NEW!")
+  ENDIF(NOT "${P3}" STREQUAL "NEW")
 ENDIF(POLICY CMP0003)
 
 # Choose whether to test CMakeLib.

+ 5 - 0
Tests/ComplexRelativePaths/CMakeLists.txt

@@ -7,6 +7,11 @@ PROJECT (Complex)
 # Try setting a new policy.  The IF test is for coverage.
 IF(POLICY CMP0003)
   CMAKE_POLICY(SET CMP0003 NEW)
+
+  CMAKE_POLICY(GET CMP0003 P3)
+  IF(NOT "${P3}" STREQUAL "NEW")
+    MESSAGE(FATAL_ERROR "CMAKE_POLICY(GET) did not report NEW!")
+  ENDIF(NOT "${P3}" STREQUAL "NEW")
 ENDIF(POLICY CMP0003)
 
 # Choose whether to test CMakeLib.