diff --git a/Source/cmCMakeMinimumRequired.cxx b/Source/cmCMakeMinimumRequired.cxx index 8d4aaf968..54acb898c 100644 --- a/Source/cmCMakeMinimumRequired.cxx +++ b/Source/cmCMakeMinimumRequired.cxx @@ -108,9 +108,6 @@ bool cmCMakeMinimumRequired cmSystemTools::SetFatalErrorOccured(); } - // set the policy version as well - this->Makefile->SetPolicyVersion(version_string.c_str()); - return true; } diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx index f2ce3daec..2a8d3a4d1 100644 --- a/Source/cmConfigureFileCommand.cxx +++ b/Source/cmConfigureFileCommand.cxx @@ -42,19 +42,15 @@ bool cmConfigureFileCommand // for CMake 2.0 and earlier CONFIGURE_FILE defaults to the FinalPass, - // after 2.0 it only does InitialPass, this is policy CMP_0003 - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP_0003)) - { - case cmPolicies::WARN: - cmSystemTools::Message( - this->Makefile->GetPolicies()->GetPolicyWarning - (cmPolicies::CMP_0003).c_str(),"Warning"); - case cmPolicies::OLD: - this->Immediate = false; - break; - default: - this->Immediate = true; - } + // after 2.0 it only does InitialPass + this->Immediate = false; + const char* versionValue + = this->Makefile->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY"); + if (versionValue && atof(versionValue) > 2.0) + { + this->Immediate = true; + } + this->AtOnly = false; for(unsigned int i=2;i < args.size();++i) diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 768db326b..24ca7a400 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -18,6 +18,7 @@ #include "cmListFileLexer.h" #include "cmSystemTools.h" +#include "cmMakefile.h" #include @@ -29,7 +30,9 @@ bool cmListFileCacheParseFunction(cmListFileLexer* lexer, cmListFileFunction& function, const char* filename); -bool cmListFile::ParseFile(const char* filename, bool requireProjectCommand) +bool cmListFile::ParseFile(const char* filename, + bool topLevel, + cmMakefile *mf) { if(!cmSystemTools::FileExists(filename)) { @@ -115,7 +118,60 @@ bool cmListFile::ParseFile(const char* filename, bool requireProjectCommand) cmListFileLexer_Delete(lexer); - if(requireProjectCommand) + // do we need a cmake_policy(VERSION call? + if(topLevel) + { + bool hasPolicy = false; + // search for the right policy command + for(std::vector::iterator i + = this->Functions.begin(); + i != this->Functions.end(); ++i) + { + if (cmSystemTools::LowerCase(i->Name) == "cmake_policy" && + i->Arguments.size() && + cmSystemTools::LowerCase(i->Arguments[0].Value) == "version") + { + hasPolicy = true; + break; + } + if (cmSystemTools::LowerCase(i->Name) == "cmake_minimum_required") + { + hasPolicy = true; + break; + } + } + // if no policy command is found this is an error + if(!hasPolicy) + { + // add in the old CMAKE_BACKWARDS_COMPATIBILITY var for old CMake compatibility + if (!mf->GetCacheManager()-> + GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")) + { + mf->AddCacheDefinition + ("CMAKE_BACKWARDS_COMPATIBILITY", "2.6", + "For backwards compatibility, what version of CMake commands and " + "syntax should this version of CMake try to support.", + cmCacheManager::STRING); + } + + switch (mf->GetPolicyStatus(cmPolicies::CMP_0000)) + { + case cmPolicies::WARN: + cmSystemTools::Message( + mf->GetPolicies()->GetPolicyWarning + (cmPolicies::CMP_0000).c_str(),"Warning"); + case cmPolicies::OLD: + break; + default: + cmSystemTools::Error( + mf->GetPolicies()->GetRequiredPolicyError + (cmPolicies::CMP_0000).c_str()); + return false; + } + } + } + + if(topLevel) { bool hasProject = false; // search for a project command diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 039a52d43..b1eaa81b4 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -26,6 +26,8 @@ * cmake list files. */ +class cmMakefile; + struct cmListFileArgument { cmListFileArgument(): Value(), Quoted(false), FilePath(0), Line(0) {} @@ -62,7 +64,9 @@ struct cmListFile :ModifiedTime(0) { } - bool ParseFile(const char* path, bool requireProjectCommand); + bool ParseFile(const char* path, + bool topLevel, + cmMakefile *mf); long int ModifiedTime; std::vector Functions; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 370439d79..df93dc0c3 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -46,9 +46,6 @@ cmMakefile::cmMakefile() { this->DefinitionStack.push_back(DefinitionMap()); - // Enter a policy level for this directory. - this->PushPolicy(); - // Setup the default include file regular expression (match everything). this->IncludeFileRegularExpression = "^.*$"; // Setup the default include complaint regular expression (match nothing). @@ -138,7 +135,6 @@ cmMakefile::cmMakefile(const cmMakefile& mf) this->PreOrder = mf.PreOrder; this->ListFileStack = mf.ListFileStack; this->Initialize(); - this->PushPolicy(); } //---------------------------------------------------------------------------- @@ -147,6 +143,9 @@ void cmMakefile::Initialize() this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)"); this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)"); this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)"); + + // Enter a policy level for this directory. + this->PushPolicy(); } unsigned int cmMakefile::GetCacheMajorVersion() @@ -208,7 +207,11 @@ cmMakefile::~cmMakefile() delete b; } this->FunctionBlockers.clear(); - this->PolicyStack.pop_back(); + if (this->PolicyStack.size() != 1) + { + cmSystemTools::Error("Internal CMake Error, Policy Stack has not been" + " popped properly"); + } } void cmMakefile::PrintStringVector(const char* s, @@ -453,7 +456,7 @@ bool cmMakefile::ReadListFile(const char* filename_in, *fullPath=filenametoread; } cmListFile cacheFile; - if( !cacheFile.ParseFile(filenametoread, requireProjectCommand) ) + if( !cacheFile.ParseFile(filenametoread, requireProjectCommand, this) ) { // pop the listfile off the stack this->ListFileStack.pop_back(); diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 3e9373be9..f5e8ff9e9 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -89,12 +89,13 @@ cmPolicies::cmPolicies() "or cmake_minimum_required call.", "CMake requires that projects specify what version of CMake they have " "been written to. The easiest way to do this is by placing a call to " - "cmake_policy such as the following cmake_policy(VERSION 2.6) Replace " + "cmake_policy at the top of your CMakeLists file. For example: " + "cmake_policy(VERSION 2.6) Replace " "2.6 in that example with the verison of CMake you are writing to. " "This policy is being put in place because it aids us in detecting " "and maintaining backwards compatibility.", 2,6,0, cmPolicies::WARN); - this->PolicyStringMap["CMP_POLICY_SPECIFICATION"] = CMP_0000; +// this->PolicyStringMap["CMP_POLICY_SPECIFICATION"] = CMP_0000; this->DefinePolicy(CMP_0001, "CMP_0001", "CMake does not allow target names to include slash characters.", @@ -102,7 +103,7 @@ cmPolicies::cmPolicies() "please change the name of any targets to not use such characters." , 2,4,0, cmPolicies::REQUIRED_IF_USED); - this->PolicyStringMap["CMP_TARGET_NAMES_WITH_SLASHES"] = CMP_0001; +// this->PolicyStringMap["CMP_TARGET_NAMES_WITH_SLASHES"] = CMP_0001; this->DefinePolicy(CMP_0002, "CMP_0002", "CMake requires that target names be globaly unique.", @@ -110,7 +111,7 @@ cmPolicies::cmPolicies() "please change the name of any targets to not use such characters." , 2,6,0, cmPolicies::WARN); - this->PolicyStringMap["CMP_REQUIRE_UNIQUE_TARGET_NAMES"] = CMP_0002; +// this->PolicyStringMap["CMP_REQUIRE_UNIQUE_TARGET_NAMES"] = CMP_0002; this->DefinePolicy(CMP_0003, "CMP_0003", "CMake configures file immediately after 2.0.", @@ -120,7 +121,7 @@ cmPolicies::cmPolicies() "configure the file right when the command is invoked." , 2,2,0, cmPolicies::NEW); - this->PolicyStringMap["CMP_CONFIGURE_FILE_IMMEDIATE"] = CMP_0003; +// this->PolicyStringMap["CMP_CONFIGURE_FILE_IMMEDIATE"] = CMP_0003; } @@ -182,23 +183,6 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf, { return false; } - - // add in the old CMAKE_BACKWARDS_COMPATIBILITY var for old CMake compatibility - if ((majorVer == 2 && minorVer <= 4) || majorVer < 2) - { - if (!mf->GetCacheManager()-> - GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")) - { - cmOStringStream v; - v << majorVer << "." << minorVer << "." << patchVer; - mf->AddCacheDefinition - ("CMAKE_BACKWARDS_COMPATIBILITY", v.str().c_str(), - "For backwards compatibility, what version of CMake commands and " - "syntax should this version of CMake try to support.", - cmCacheManager::STRING); - } - } - // now loop over all the policies and set them as appropriate std::map::iterator i @@ -365,7 +349,7 @@ std::string cmPolicies::GetPolicyWarning(cmPolicies::PolicyID id) cmOStringStream msg; msg << "WARNING: Policy " << pos->second->IDString << " is not set: " - "" << pos->second->ShortDescription << "\n" + "" << pos->second->ShortDescription << " " "Run \"cmake --help-policy " << pos->second->IDString << "\" for " "policy details. Use the cmake_policy command to set the policy " "and suppress this warning."; @@ -428,10 +412,40 @@ void cmPolicies::GetDocumentation(std::vector& v) { std::string full; full += i->second->LongDescription; + full += "\nThis policy was introduced in CMake version "; + full += i->second->GetVersionString(); + full += ". The version of CMake you are running "; // add in some more text here based on status - // switch (i->second->Status) - // { - // case cmPolicies::WARN: + switch (i->second->Status) + { + case cmPolicies::WARN: + full += "defaults to warning about this policy. You can either " + "suppress the warning without fixing the issue by adding a " + "cmake_policy(SET "; + full += i->second->IDString; + full += " OLD) command to the top of your CMakeLists file or " + "you can change your code to use the new behavior and add " + "cmake_policy(SET "; + full += i->second->IDString; + full += " NEW) to your CMakeList file. If you are fixing all " + "issues with a new version of CMake you can add " + "cmake_policy(VERSION #.#) where #.# is the verison of CMake " + "you are updating to. This will tell CMake that you have fixed " + "all issues to use the new behavior."; + case cmPolicies::OLD: + full += "defaults to the old behavior for this policy."; + break; + case cmPolicies::NEW: + full += "defaults to the new behavior for this policy."; + break; + case cmPolicies::REQUIRED_IF_USED: + full += "requires the new behavior for this policy." + "if you usee it."; + break; + case cmPolicies::REQUIRED_ALWAYS: + full += "requires the new behavior for this policy."; + break; + } cmDocumentationEntry e(i->second->IDString.c_str(), i->second->ShortDescription.c_str(),