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
This commit is contained in:
Brad King 2008-03-31 13:33:09 -04:00
parent 3652a8e913
commit e3666a1de5
4 changed files with 79 additions and 36 deletions

View File

@ -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");
}
}
}

View File

@ -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)
{

View File

@ -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);
};

View File

@ -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
);