From e3666a1de575c7a2c4ef757b3f6e9a63fdfa2b8e Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 31 Mar 2008 13:33:09 -0400 Subject: [PATCH] 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 --- Source/cmListFileCache.cxx | 30 ++++------------- Source/cmMakefile.cxx | 67 +++++++++++++++++++++++++++++++------- Source/cmMakefile.h | 8 +++++ Source/cmPolicies.cxx | 10 +++++- 4 files changed, 79 insertions(+), 36 deletions(-) diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 27a4878b9..c7383eafe 100644 --- a/Source/cmListFileCache.cxx +++ b/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"); } } } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index f09c605e8..135dc287d 100644 --- a/Source/cmMakefile.cxx +++ b/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) { diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index b91ddb45e..d8873f4c6 100644 --- a/Source/cmMakefile.h +++ b/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 PolicyMap; std::vector PolicyStack; + + bool CheckCMP0000; + + // Enforce rules about CMakeLists.txt files. + void EnforceDirectoryLevelRules(bool endScopeNicely); }; diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index b37171b78..b69a7198e 100644 --- a/Source/cmPolicies.cxx +++ b/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 );