소스 검색

ENH: Allow policy CMP0000 to be set explicitly

  - Message for missing cmake_minimum_required is not issued
    until the end of processing the top CMakeLists.txt file
  - During processing a cmake_policy command may set behavior
  - OLD behavior is to silently ignore the problem
  - NEW behavior is to issue an error instead of a warning
Brad King 17 년 전
부모
커밋
e3666a1de5
4개의 변경된 파일79개의 추가작업 그리고 36개의 파일을 삭제
  1. 6 24
      Source/cmListFileCache.cxx
  2. 56 11
      Source/cmMakefile.cxx
  3. 8 0
      Source/cmMakefile.h
  4. 9 1
      Source/cmPolicies.cxx

+ 6 - 24
Source/cmListFileCache.cxx

@@ -171,30 +171,12 @@ bool cmListFile::ParseFile(const char* filename,
       
       if (isProblem)
       {
-      cmOStringStream msg;
-      msg << "No cmake_minimum_required command is present.  "
-          << "A line of code such as\n"
-          << "  cmake_minimum_required(VERSION "
-          << cmVersion::GetMajorVersion() << "."
-          << cmVersion::GetMinorVersion()
-          << ")\n"
-          << "should be added at the top of the file.  "
-          << "The version specified may be lower if you wish to "
-          << "support older CMake versions for this project.  "
-          << "For more information run "
-          << "\"cmake --help-policy CMP0000\".";
-      switch (mf->GetPolicyStatus(cmPolicies::CMP0000))
-        {
-        case cmPolicies::WARN:
-          mf->IssueMessage(cmake::AUTHOR_WARNING, msg.str().c_str());
-        case cmPolicies::OLD:
-          // Implicitly set the version for the user.
-          mf->SetPolicyVersion("2.4");
-          break;
-        default:
-          mf->IssueMessage(cmake::FATAL_ERROR, msg.str().c_str());
-          return false;
-        }
+      // Tell the top level cmMakefile to diagnose
+      // this violation of CMP0000.
+      mf->SetCheckCMP0000(true);
+
+      // Implicitly set the version for the user.
+      mf->SetPolicyVersion("2.4");
       }
     }
   }

+ 56 - 11
Source/cmMakefile.cxx

@@ -146,6 +146,10 @@ void cmMakefile::Initialize()
 
   // Enter a policy level for this directory.
   this->PushPolicy();
+
+  // By default the check is not done.  It is enabled by
+  // cmListFileCache in the top level if necessary.
+  this->CheckCMP0000 = false;
 }
 
 unsigned int cmMakefile::GetCacheMajorVersion()
@@ -561,19 +565,11 @@ bool cmMakefile::ReadListFile(const char* filename_in,
       }
     }
 
-  // If this is the directory-level CMakeLists.txt file then enforce
-  // policy stack depth.
+  // If this is the directory-level CMakeLists.txt file then perform
+  // some extra checks.
   if(this->ListFileStack.size() == 1)
     {
-    while(this->PolicyStack.size() > 1)
-      {
-      if(endScopeNicely)
-        {
-        this->IssueMessage(cmake::FATAL_ERROR, 
-                           "cmake_policy PUSH without matching POP");
-        }
-      this->PopPolicy(false);
-      }
+    this->EnforceDirectoryLevelRules(endScopeNicely);
     }
 
   this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
@@ -585,6 +581,55 @@ bool cmMakefile::ReadListFile(const char* filename_in,
   return true;
 }
 
+//----------------------------------------------------------------------------
+void cmMakefile::EnforceDirectoryLevelRules(bool endScopeNicely)
+{
+  // Enforce policy stack depth.
+  while(this->PolicyStack.size() > 1)
+    {
+    if(endScopeNicely)
+      {
+      this->IssueMessage(cmake::FATAL_ERROR,
+                         "cmake_policy PUSH without matching POP");
+      }
+    this->PopPolicy(false);
+    }
+
+  // Diagnose a violation of CMP0000 if necessary.
+  if(this->CheckCMP0000)
+    {
+    cmOStringStream msg;
+    msg << "No cmake_minimum_required command is present.  "
+        << "A line of code such as\n"
+        << "  cmake_minimum_required(VERSION "
+        << cmVersion::GetMajorVersion() << "."
+        << cmVersion::GetMinorVersion()
+        << ")\n"
+        << "should be added at the top of the file.  "
+        << "The version specified may be lower if you wish to "
+        << "support older CMake versions for this project.  "
+        << "For more information run "
+        << "\"cmake --help-policy CMP0000\".";
+    switch (this->GetPolicyStatus(cmPolicies::CMP0000))
+      {
+      case cmPolicies::WARN:
+        // Warn because the user did not provide a mimimum required
+        // version.
+        this->IssueMessage(cmake::AUTHOR_WARNING, msg.str().c_str());
+      case cmPolicies::OLD:
+        // OLD behavior is to use policy version 2.4 set in
+        // cmListFileCache.
+        break;
+      case cmPolicies::REQUIRED_IF_USED:
+      case cmPolicies::REQUIRED_ALWAYS:
+      case cmPolicies::NEW:
+        // NEW behavior is to issue an error.
+        this->IssueMessage(cmake::FATAL_ERROR, msg.str().c_str());
+        cmSystemTools::SetFatalErrorOccured();
+        return;
+      }
+    }
+}
 
 void cmMakefile::AddCommand(cmCommand* wg)
 {

+ 8 - 0
Source/cmMakefile.h

@@ -793,6 +793,9 @@ public:
   void IssueMessage(cmake::MessageType t,
                     std::string const& text) const;
 
+  /** Set whether or not to report a CMP0000 violation.  */
+  void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
+
 protected:
   // add link libraries and directories to the target
   void AddGlobalLinkInformation(const char* name, cmTarget& target);
@@ -904,6 +907,11 @@ private:
   typedef std::map<cmPolicies::PolicyID,
                    cmPolicies::PolicyStatus> PolicyMap;
   std::vector<PolicyMap> PolicyStack;
+
+  bool CheckCMP0000;
+
+  // Enforce rules about CMakeLists.txt files.
+  void EnforceDirectoryLevelRules(bool endScopeNicely);
 };
 
 

+ 9 - 1
Source/cmPolicies.cxx

@@ -101,7 +101,15 @@ cmPolicies::cmPolicies()
     "(such as \"2.6\").  "
     "The command will ensure that at least the given version of CMake is "
     "running and help newer versions be compatible with the project.  "
-    "See documentation of cmake_minimum_required for details.",
+    "See documentation of cmake_minimum_required for details.\n"
+    "Note that the command invocation must appear in the CMakeLists.txt "
+    "file itself; a call in an included file is not sufficient.  "
+    "However, the cmake_policy command may be called to set policy "
+    "CMP0000 to OLD or NEW behavior explicitly.  "
+    "The OLD behavior is to silently ignore the missing invocation.  "
+    "The NEW behavior is to issue an error instead of a warning.  "
+    "An included file may set CMP0000 explicitly to affect how this "
+    "policy is enforced for the main CMakeLists.txt file.",
     2,6,0, cmPolicies::WARN
     );