Commit 5233b75a authored by Brad King's avatar Brad King
Browse files

ENH: Improve handling of old-style compatibility.

  - Remove CMP_0001 (no slash in target name) and restore
    old CMAKE_BACKWARDS_COMPATIBILITY check for it
  - Replace all checks of CMAKE_BACKWARDS_COMPATIBILITY
    with cmLocalGenerator::NeedBackwardsCompatibility calls
  - Create new CMP_0001 to determine whether or not
    CMAKE_BACKWARDS_COMPATIBILITY is used.
    (old = use, new = ignore)
  - Show CMAKE_BACKWARDS_COMPATIBILITY in cache only when
    CMP_0001 is set to OLD or WARN
  - Update documentation of cmake_policy and cmake_minimum_required
    to indicate their relationship and the 2.4 version boundary
  - When no cmake policy version is set in top level makefile
    implicitly call cmake_policy(VERSION 2.4) which restores
    CMAKE_BACKWARDS_COMPATIBILITY and other 2.4 compatibility
  - Fix tests MakeClean and Preprocess to call
    cmake_policy(VERSION 2.6) because they depend on new policies
parent fcce2f3b
......@@ -21,18 +21,6 @@ bool cmAddCustomTargetCommand
::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
// This enum must be before an enum is used in a switch statment.
// If not there is an ICE on the itanium version of gcc we are running
// on dash8
// Keep track of parser state.
enum tdoing {
doing_command,
doing_depends,
doing_working_directory,
doing_comment,
doing_verbatim
};
if(args.size() < 1 )
{
this->SetError("called with incorrect number of arguments");
......@@ -41,34 +29,20 @@ bool cmAddCustomTargetCommand
// Check the target name.
if(args[0].find_first_of("/\\") != args[0].npos)
{
// slashes are not allowed anymore in taret names CMP_0001
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP_0001))
{
case cmPolicies::WARN:
this->Makefile->IssueWarning(
this->Makefile->GetPolicies()->GetPolicyWarning
(cmPolicies::CMP_0001));
case cmPolicies::OLD:
// if (this->Makefile->IsBWCompatibilityLessThan(2,2))
// {
// break;
// }
case cmPolicies::NEW:
this->SetError("You included a / or \\ in your target name and "
"this is not allowed according to policy CMP_0001. Run "
"cmake --help-policy CMP_0001 for more information.");
return false;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
this->Makefile->IssueError(
this->Makefile->GetPolicies()->GetRequiredPolicyError
(cmPolicies::CMP_0001).c_str()
);
return false;
if(!this->Makefile->NeedBackwardsCompatibility(2,2))
{
cmOStringStream e;
e << "called with invalid target name \"" << args[0]
<< "\". Target names may not contain a slash. "
<< "Use ADD_CUSTOM_COMMAND to generate files. "
<< "Set CMAKE_BACKWARDS_COMPATIBILITY to 2.2 "
<< "or lower to skip this check.";
this->SetError(e.str().c_str());
return false;
}
}
}
// Accumulate one command line at a time.
cmCustomCommandLine currentLine;
......@@ -83,6 +57,13 @@ bool cmAddCustomTargetCommand
const char* comment = 0;
// Keep track of parser state.
enum tdoing {
doing_command,
doing_depends,
doing_working_directory,
doing_comment,
doing_verbatim
};
tdoing doing = doing_command;
// Look for the ALL option.
......
......@@ -70,6 +70,13 @@ public:
" [FATAL_ERROR])\n"
"If the current version of CMake is lower than that required "
"it will stop processing the project and report an error.\n"
"When a version higher than 2.4 is specified the command implicitly "
"invokes\n"
" cmake_policy(VERSION major[.minor[.patch]])\n"
"which sets the cmake policy version level to the version specified.\n"
"When version 2.4 or lower is given the command implicitly invokes\n"
" cmake_policy(VERSION 2.4)\n"
"which enables compatibility features for CMake 2.4 and lower.\n"
"The FATAL_ERROR option is accepted but ignored. It is left from "
"CMake versions 2.4 and lower in which failure to meet the minimum "
"version was a warning by default.";
......
......@@ -76,7 +76,11 @@ public:
"to WARN, which is like OLD but also produces a warning. "
"This effectively requests behavior preferred as of a given CMake "
"version and tells newer CMake versions to warn about their new "
"policies."
"policies. "
"The policy version specified must be at least 2.4 or the command "
"will report an error. "
"In order to get compatibility features supporting versions earlier "
"than 2.4 see documentation of policy CMP_0001."
"\n"
" cmake_policy(SET <CMP_NNNN> NEW)\n"
" cmake_policy(SET <CMP_NNNN> OLD)\n"
......
......@@ -40,29 +40,10 @@ bool cmConfigureFileCommand
this->CopyOnly = false;
this->EscapeQuotes = false;
// for CMake 2.0 and earlier CONFIGURE_FILE defaults to the FinalPass,
// 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->Immediate = !this->Makefile->NeedBackwardsCompatibility(2,0);
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP_0003))
{
case cmPolicies::WARN:
case cmPolicies::OLD:
break;
case cmPolicies::NEW:
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
this->Immediate = true;
}
this->AtOnly = false;
for(unsigned int i=2;i < args.size();++i)
{
......
......@@ -109,19 +109,7 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
// CMake versions below 2.3 did not search all these extra
// locations. Preserve compatibility unless a modern argument is
// passed.
bool compatibility = false;
const char* versionValue =
this->Makefile->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
int major = 0;
int minor = 0;
if(versionValue && sscanf(versionValue, "%d.%d", &major, &minor) != 2)
{
versionValue = 0;
}
if(versionValue && (major < 2 || major == 2 && minor < 3))
{
compatibility = true;
}
bool compatibility = this->Makefile->NeedBackwardsCompatibility(2,3);
// copy argsIn into args so it can be modified,
// in the process extract the DOC "documentation"
......
......@@ -149,6 +149,9 @@ bool cmListFile::ParseFile(const char* filename,
mf->IssueWarning(
mf->GetPolicies()->GetPolicyWarning(cmPolicies::CMP_0000)
);
// Implicitly set the version for the user.
mf->SetPolicyVersion("2.4");
case cmPolicies::OLD:
break;
default:
......
......@@ -1195,15 +1195,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
// CMake versions below 2.0 would add the source tree to the -I path
// automatically. Preserve compatibility.
const char* versionValue =
this->Makefile->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
int major = 0;
int minor = 0;
if(versionValue && sscanf(versionValue, "%d.%d", &major, &minor) != 2)
{
versionValue = 0;
}
if(versionValue && major < 2)
if(this->NeedBackwardsCompatibility(1,9))
{
includeSourceDir = true;
}
......@@ -2679,6 +2671,28 @@ bool cmLocalGenerator::NeedBackwardsCompatibility(unsigned int major,
unsigned int minor,
unsigned int patch)
{
// Check the policy to decide whether to pay attention to this
// variable.
switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP_0001))
{
case cmPolicies::WARN:
// WARN is just OLD without warning because user code does not
// always affect whether this check is done.
case cmPolicies::OLD:
// Old behavior is to check the variable.
break;
case cmPolicies::NEW:
// New behavior is to ignore the variable.
return false;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
// This will never be the case because the only way to require
// the setting is to require the user to specify version policy
// 2.6 or higher. Once we add that requirement then this whole
// method can be removed anyway.
return false;
}
// Compatibility is needed if CMAKE_BACKWARDS_COMPATIBILITY is set
// equal to or lower than the given version.
unsigned int actual_compat = this->GetBackwardsCompatibility();
......
......@@ -1143,13 +1143,8 @@ void cmMakefile::AddLinkLibraryForTarget(const char *target,
this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0,lib);
if(tgt)
{
bool allowModules = true;
const char* versionValue
= this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
if (versionValue && (atof(versionValue) >= 2.4) )
{
allowModules = false;
}
// CMake versions below 2.4 allowed linking to modules.
bool allowModules = this->NeedBackwardsCompatibility(2,3);
// if it is not a static or shared library then you can not link to it
if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) ||
(tgt->GetType() == cmTarget::SHARED_LIBRARY) ||
......@@ -2092,15 +2087,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
<< ":" << line << ":\n"
<< parser.GetError() << ", when parsing string \""
<< source.c_str() << "\"";
const char* versionValue
= this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
int major = 0;
int minor = 0;
if ( versionValue )
{
sscanf(versionValue, "%d.%d", &major, &minor);
}
if ( major < 2 || major == 2 && minor < 1 )
if(this->NeedBackwardsCompatibility(2,0))
{
cmSystemTools::Error(error.str().c_str());
cmSystemTools::SetFatalErrorOccured();
......@@ -3333,9 +3320,7 @@ bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
"\n"
"If you are building an older project it is possible that "
"it violated this rule but was working accidentally because "
"CMake did not previously diagnose this problem. "
"Set CMAKE_BACKWARDS_COMPATIBILITY to 2.4 or lower to disable "
"this error.\n";
"CMake did not previously diagnose this problem.\n";
if(isCustom && existing->GetType() == cmTarget::UTILITY)
{
e <<
......@@ -3422,6 +3407,26 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
IsValidPolicyStatus(id,status))
{
this->PolicyStack.back()[id] = status;
// Special hook for presenting compatibility variable as soon as
// the user requests it.
if(id == cmPolicies::CMP_0001 &&
(status == cmPolicies::WARN || status == cmPolicies::OLD))
{
if(!(this->GetCacheManager()
->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
{
// Set it to 2.4 because that is the last version where the
// variable had meaning.
this->AddCacheDefinition
("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
"For backwards compatibility, what version of CMake "
"commands and "
"syntax should this version of CMake try to support.",
cmCacheManager::STRING);
}
}
return true;
}
return false;
......
......@@ -84,7 +84,8 @@ public:
cmPolicies::cmPolicies()
{
// define all the policies
this->DefinePolicy(CMP_0000, "CMP_0000",
this->DefinePolicy(
CMP_0000, "CMP_0000",
"Missing a CMake version specification. You must have a cmake_policy "
"call.",
"CMake requires that projects specify what version of CMake they have "
......@@ -94,36 +95,32 @@ cmPolicies::cmPolicies()
"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->DefinePolicy(CMP_0001, "CMP_0001",
"CMake does not allow target names to include slash characters.",
"CMake requires that target names not include any / or \\ characters "
"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->DefinePolicy(CMP_0002, "CMP_0002",
"CMake requires that target names be globaly unique.",
"CMake requires that target names not include any / or \\ characters "
"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;
2,6,0, cmPolicies::WARN
);
this->DefinePolicy(CMP_0003, "CMP_0003",
"CMake configures file immediately after 2.0.",
"In CMake 2.0 and earlier the configure_file command would not "
"configure the file until after processing all CMakeLists files. "
"In CMake 2.2 and later the default behavior is that it will "
"configure the file right when the command is invoked."
,
2,6,0, cmPolicies::NEW);
// this->PolicyStringMap["CMP_CONFIGURE_FILE_IMMEDIATE"] = CMP_0003;
this->DefinePolicy(
CMP_0001, "CMP_0001",
"CMAKE_BACKWARDS_COMPATIBILITY should no longer be used.",
"The OLD behavior is to check CMAKE_BACKWARDS_COMPATIBILITY and present "
"it to the user. "
"The NEW behavior is to ignore CMAKE_BACKWARDS_COMPATIBILITY "
"completely.\n"
"In CMake 2.4 and below the variable CMAKE_BACKWARDS_COMPATIBILITY was "
"used to request compatibility with earlier versions of CMake. "
"In CMake 2.6 and above all compatibility issues are handled by policies "
"and the cmake_policy command. "
"However, CMake must still check CMAKE_BACKWARDS_COMPATIBILITY for "
"projects written for CMake 2.4 and below.",
2,6,0, cmPolicies::WARN
);
}
this->DefinePolicy(
CMP_0002, "CMP_0002",
"CMake requires that target names be globaly unique.",
"....",
2,6,0, cmPolicies::WARN
);
}
cmPolicies::~cmPolicies()
{
......@@ -187,27 +184,18 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
// it is an error if the policy version is less than 2.4
if (majorVer < 2 || majorVer == 2 && minorVer < 4)
{
mf->IssueError("An attempt was made to set the policy version of "
"CMake to something earlier than 2.4, this is an error!");
mf->IssueError(
"An attempt was made to set the policy version of CMake to something "
"earlier than \"2.4\". "
"In CMake 2.4 and below backwards compatibility was handled with the "
"CMAKE_BACKWARDS_COMPATIBILITY variable. "
"In order to get compatibility features supporting versions earlier "
"than 2.4 set policy CMP_0001 to OLD to tell CMake to check the "
"CMAKE_BACKWARDS_COMPATIBILITY variable. "
"One way to so this is to set the policy version to 2.4 exactly."
);
}
// if the version is 2.4 then make sure the backwards compatibility variable is visible
if (majorVer == 2 && minorVer == 4)
{
// set the default BACKWARDS compatibility to be visible
mf->GetCacheManager()->GetCacheIterator(
"CMAKE_BACKWARDS_COMPATIBILITY").SetType
(cmCacheManager::STRING);
// const char *cbcValue =
// mf->GetCacheManager()->
// GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY");
// mf->AddCacheDefinition
// ("CMAKE_BACKWARDS_COMPATIBILITY",cbcValue,
// "For backwards compatibility, what version of CMake commands and "
// "syntax should this version of CMake allow.",
// cmCacheManager::STRING);
}
// now loop over all the policies and set them as appropriate
std::map<cmPolicies::PolicyID,cmPolicy *>::iterator i
= this->Policies.begin();
......
......@@ -38,12 +38,12 @@ public:
enum PolicyStatus { OLD, WARN, NEW, REQUIRED_IF_USED, REQUIRED_ALWAYS };
static const char* PolicyStatusNames[];
enum PolicyID {CMP_0000, CMP_POLICY_SPECIFICATION = CMP_0000,
CMP_0001, CMP_TARGET_NAMES_WITH_SLASHES = CMP_0001,
CMP_0002, CMP_REQUIRE_UNIQUE_TARGET_NAMES = CMP_0002,
CMP_0003, CMP_CONFIGURE_FILE_IMMEDIATE = CMP_0003
};
enum PolicyID
{
CMP_0000, // Policy version specification
CMP_0001, // Ignore old compatibility variable
CMP_0002
};
///! convert a string policy ID into a number
bool GetPolicyID(const char *id, /* out */ cmPolicies::PolicyID &pid);
......
......@@ -1899,19 +1899,6 @@ int cmake::ActualConfigure()
cmCacheManager::INTERNAL);
}
// set the default BACKWARDS compatibility to the current version
if(!this->CacheManager->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY"))
{
char ver[256];
sprintf(ver,"%i.%i",cmVersion::GetMajorVersion(),
cmVersion::GetMinorVersion());
this->CacheManager->AddCacheEntry
("CMAKE_BACKWARDS_COMPATIBILITY",ver,
"For backwards compatibility, what version of CMake commands and "
"syntax should this version of CMake allow.",
cmCacheManager::INTERNAL);
}
// no generator specified on the command line
if(!this->GlobalGenerator)
{
......@@ -2392,20 +2379,6 @@ int cmake::LoadCache()
{
return -3;
}
// set the default BACKWARDS compatibility to the current version
if(!this->CacheManager->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY"))
{
char ver[256];
sprintf(ver,"%i.%i",cmVersion::GetMajorVersion(),
cmVersion::GetMinorVersion());
this->CacheManager->AddCacheEntry
("CMAKE_BACKWARDS_COMPATIBILITY",ver,
"For backwards compatibility, what version of CMake commands and "
"syntax should this version of CMake allow.",
cmCacheManager::INTERNAL);
}
return 0;
}
......
cmake_policy(VERSION 2.6)
PROJECT(ToClean)
# Build a simple project.
......
cmake_policy(VERSION 2.6)
project(Preprocess)
# This test is meant both as a test and as a reference for supported
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment