summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2014-01-29 14:28:01 (GMT)
committerBrad King <brad.king@kitware.com>2014-01-29 14:45:18 (GMT)
commit7e142c5ac2be11097f7ff905b1606179803043d7 (patch)
treed7565d46f43fa420270d0111bd30e5279c58c9dc /Source
parent16d040c958c68c38b2c0642b4094245af28c1910 (diff)
downloadCMake-7e142c5ac2be11097f7ff905b1606179803043d7.zip
CMake-7e142c5ac2be11097f7ff905b1606179803043d7.tar.gz
CMake-7e142c5ac2be11097f7ff905b1606179803043d7.tar.bz2
project: Manage VERSION variables
Teach the project() command to set variables {PROJECT,<PROJECT-NAME>}_VERSION{,_MAJOR,_MINOR,_PATCH,_TWEAK} holding the project version number and its components. Add project() command option "VERSION" to specify the version explicitly, and default to the empty string when it is not given. Since this clears variables when no VERSION is given, this may change behavior for existing projects that set the version variables themselves prior to calling project(). Add policy CMP0048 for compatibility. Suggested-by: Alex Neundorf <neundorf@kde.org>
Diffstat (limited to 'Source')
-rw-r--r--Source/cmPolicies.cxx5
-rw-r--r--Source/cmPolicies.h1
-rw-r--r--Source/cmProjectCommand.cxx137
3 files changed, 142 insertions, 1 deletions
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index a1451f1..e191256 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -341,6 +341,11 @@ cmPolicies::cmPolicies()
CMP0047, "CMP0047",
"Use QCC compiler id for the qcc drivers on QNX.",
3,0,0,0, cmPolicies::WARN);
+
+ this->DefinePolicy(
+ CMP0048, "CMP0048",
+ "project() command manages VERSION variables.",
+ 3,0,0,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index d1bba7b..42271dd 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -101,6 +101,7 @@ public:
CMP0045, ///< Error on non-existent target in get_target_property
CMP0046, ///< Error on non-existent dependency in add_dependencies
CMP0047, ///< Use QCC compiler id for the qcc drivers on QNX.
+ CMP0048, ///< project() command manages VERSION variables
/** \brief Always the last entry.
*
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 1dcb72b..a9ce0cc 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -62,8 +62,12 @@ bool cmProjectCommand
"Value Computed by CMake", cmCacheManager::STATIC);
}
+ bool haveVersion = false;
bool haveLanguages = false;
+ std::string version;
std::vector<std::string> languages;
+ enum Doing { DoingLanguages, DoingVersion };
+ Doing doing = DoingLanguages;
for(size_t i = 1; i < args.size(); ++i)
{
if(args[i] == "LANGUAGES")
@@ -76,18 +80,149 @@ bool cmProjectCommand
return true;
}
haveLanguages = true;
+ doing = DoingLanguages;
}
- else
+ else if (args[i] == "VERSION")
+ {
+ if(haveVersion)
+ {
+ this->Makefile->IssueMessage
+ (cmake::FATAL_ERROR, "VERSION may be specified at most once.");
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+ haveVersion = true;
+ doing = DoingVersion;
+ }
+ else if(doing == DoingVersion)
+ {
+ doing = DoingLanguages;
+ version = args[i];
+ }
+ else // doing == DoingLanguages
{
languages.push_back(args[i]);
}
}
+ if (haveVersion && !haveLanguages && !languages.empty())
+ {
+ this->Makefile->IssueMessage
+ (cmake::FATAL_ERROR,
+ "project with VERSION must use LANGUAGES before language names.");
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
if (haveLanguages && languages.empty())
{
languages.push_back("NONE");
}
+ cmPolicies::PolicyStatus cmp0048 =
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0048);
+ if (haveVersion)
+ {
+ // Set project VERSION variables to given values
+ if (cmp0048 == cmPolicies::OLD ||
+ cmp0048 == cmPolicies::WARN)
+ {
+ this->Makefile->IssueMessage
+ (cmake::FATAL_ERROR,
+ "VERSION not allowed unless CMP0048 is set to NEW");
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+
+ cmsys::RegularExpression
+ vx("^([0-9]+(\\.[0-9]+(\\.[0-9]+(\\.[0-9]+)?)?)?)?$");
+ if(!vx.find(version))
+ {
+ std::string e = "VERSION \"" + version + "\" format invalid.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e);
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+
+ std::string vs;
+ const char* sep = "";
+ char vb[4][64];
+ unsigned int v[4] = {0,0,0,0};
+ int vc = sscanf(version.c_str(), "%u.%u.%u.%u",
+ &v[0], &v[1], &v[2], &v[3]);
+ for(int i=0; i < 4; ++i)
+ {
+ if(i < vc)
+ {
+ sprintf(vb[i], "%u", v[i]);
+ vs += sep;
+ vs += vb[i];
+ sep = ".";
+ }
+ else
+ {
+ vb[i][0] = 0;
+ }
+ }
+
+ std::string vv;
+ vv = args[0] + "_VERSION";
+ this->Makefile->AddDefinition("PROJECT_VERSION", vs.c_str());
+ this->Makefile->AddDefinition(vv.c_str(), vs.c_str());
+ vv = args[0] + "_VERSION_MAJOR";
+ this->Makefile->AddDefinition("PROJECT_VERSION_MAJOR", vb[0]);
+ this->Makefile->AddDefinition(vv.c_str(), vb[0]);
+ vv = args[0] + "_VERSION_MINOR";
+ this->Makefile->AddDefinition("PROJECT_VERSION_MINOR", vb[1]);
+ this->Makefile->AddDefinition(vv.c_str(), vb[1]);
+ vv = args[0] + "_VERSION_PATCH";
+ this->Makefile->AddDefinition("PROJECT_VERSION_PATCH", vb[2]);
+ this->Makefile->AddDefinition(vv.c_str(), vb[2]);
+ vv = args[0] + "_VERSION_TWEAK";
+ this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK", vb[3]);
+ this->Makefile->AddDefinition(vv.c_str(), vb[3]);
+ }
+ else if(cmp0048 != cmPolicies::OLD)
+ {
+ // Set project VERSION variables to empty
+ std::vector<std::string> vv;
+ vv.push_back("PROJECT_VERSION");
+ vv.push_back("PROJECT_VERSION_MAJOR");
+ vv.push_back("PROJECT_VERSION_MINOR");
+ vv.push_back("PROJECT_VERSION_PATCH");
+ vv.push_back("PROJECT_VERSION_TWEAK");
+ vv.push_back(args[0] + "_VERSION");
+ vv.push_back(args[0] + "_VERSION_MAJOR");
+ vv.push_back(args[0] + "_VERSION_MINOR");
+ vv.push_back(args[0] + "_VERSION_PATCH");
+ vv.push_back(args[0] + "_VERSION_TWEAK");
+ std::string vw;
+ for(std::vector<std::string>::iterator i = vv.begin();
+ i != vv.end(); ++i)
+ {
+ const char* v = this->Makefile->GetDefinition(i->c_str());
+ if(v && *v)
+ {
+ if(cmp0048 == cmPolicies::WARN)
+ {
+ vw += "\n ";
+ vw += *i;
+ }
+ else
+ {
+ this->Makefile->AddDefinition(i->c_str(), "");
+ }
+ }
+ }
+ if(!vw.empty())
+ {
+ cmOStringStream w;
+ w << (this->Makefile->GetPolicies()
+ ->GetPolicyWarning(cmPolicies::CMP0048))
+ << "\nThe following variable(s) would be set to empty:" << vw;
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+ }
+
if (languages.empty())
{
// if no language is specified do c and c++