Merge topic 'project-version-0'

0ba5891ead project: Keep leading `0` in PROJECT_VERSION components
5f84669806 Tests: Factor out RunCMake.project helper macro into module
b1f387a7ea Refactor: Use raw string literals instead of escaping
41b85968d8 Refactor: Use initializer lists instead of `push_back` series
45e85dd2b2 Refactor: Add some `const` to vars
90f91e4d21 Refactor: Replace a "magic" number w/ a named constant
638383c38f Refactor: Eliminate one-time-used variables
9b6a53292f Refactor: Eliminate `sep` from the loop

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3517
This commit is contained in:
Brad King
2019-07-17 11:27:53 +00:00
committed by Kitware Robot
15 changed files with 215 additions and 66 deletions

View File

@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.16
.. toctree::
:maxdepth: 1
CMP0096: project() preserves leading zeros in version components. </policy/CMP0096>
CMP0095: RPATH entries are properly escaped in the intermediary CMake install script. </policy/CMP0095>
Policies Introduced by CMake 3.15

25
Help/policy/CMP0096.rst Normal file
View File

@@ -0,0 +1,25 @@
CMP0096
-------
The :command:`project` command preserves leading zeros in version components.
When a ``VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]`` argument is given
to the :command:`project` command, it stores the version string in the
``PROJECT_VERSION`` variable and stores individual integer version components
in ``PROJECT_VERSION_{MAJOR,MINOR,PATCH,TWEAK}`` variables (see policy
:policy:`CMP0048`). CMake 3.15 and below dropped leading zeros from each
component. CMake 3.16 and higher prefer to preserve leading zeros. This
policy provides compatibility for projects that have not been updated to
expect the new behavior.
The ``OLD`` behavior of this policy drops leading zeros in all components,
e.g. such that version ``1.07.06`` becomes ``1.7.6``. The ``NEW`` behavior
of this policy preserves the leading zeros in all components, such that
version ``1.07.06`` remains unchanged.
This policy was introduced in CMake version 3.16. Unlike many policies, CMake
version |release| does *not* warn when this policy is not set and simply uses
the ``OLD`` behavior. Use the :command:`cmake_policy` command to set it to
``OLD`` or ``NEW`` explicitly.
.. include:: DEPRECATED.txt

View File

@@ -0,0 +1,5 @@
project-version-0
-----------------
* The :command:`project` no longer strips leading zeros in version components.
See policy :policy:`CMP0096`.

View File

@@ -283,7 +283,10 @@ class cmMakefile;
SELECT(POLICY, CMP0095, \
"RPATH entries are properly escaped in the intermediary CMake " \
"install script.", \
3, 16, 0, cmPolicies::WARN)
3, 16, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0096, \
"project() preserves leading zeros in version components.", 3, 16, \
0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \

View File

@@ -3,9 +3,12 @@
#include "cmProjectCommand.h"
#include "cmsys/RegularExpression.hxx"
#include <array>
#include <cstdio>
#include <functional>
#include <limits>
#include <sstream>
#include <stdio.h>
#include <utility>
#include "cmAlgorithms.h"
#include "cmMakefile.h"
@@ -33,25 +36,19 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
this->Makefile->SetProjectName(projectName);
std::string bindir = projectName;
bindir += "_BINARY_DIR";
std::string srcdir = projectName;
srcdir += "_SOURCE_DIR";
this->Makefile->AddCacheDefinition(
bindir, this->Makefile->GetCurrentBinaryDirectory().c_str(),
projectName + "_BINARY_DIR",
this->Makefile->GetCurrentBinaryDirectory().c_str(),
"Value Computed by CMake", cmStateEnums::STATIC);
this->Makefile->AddCacheDefinition(
srcdir, this->Makefile->GetCurrentSourceDirectory().c_str(),
projectName + "_SOURCE_DIR",
this->Makefile->GetCurrentSourceDirectory().c_str(),
"Value Computed by CMake", cmStateEnums::STATIC);
bindir = "PROJECT_BINARY_DIR";
srcdir = "PROJECT_SOURCE_DIR";
this->Makefile->AddDefinition(
bindir, this->Makefile->GetCurrentBinaryDirectory().c_str());
"PROJECT_BINARY_DIR", this->Makefile->GetCurrentBinaryDirectory().c_str());
this->Makefile->AddDefinition(
srcdir, this->Makefile->GetCurrentSourceDirectory().c_str());
"PROJECT_SOURCE_DIR", this->Makefile->GetCurrentSourceDirectory().c_str());
this->Makefile->AddDefinition("PROJECT_NAME", projectName.c_str());
@@ -205,7 +202,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
languages.emplace_back("NONE");
}
cmPolicies::PolicyStatus cmp0048 =
cmPolicies::PolicyStatus const cmp0048 =
this->Makefile->GetPolicyStatus(cmPolicies::CMP0048);
if (haveVersion) {
// Set project VERSION variables to given values
@@ -220,64 +217,87 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
cmsys::RegularExpression vx(
R"(^([0-9]+(\.[0-9]+(\.[0-9]+(\.[0-9]+)?)?)?)?$)");
if (!vx.find(version)) {
std::string e = "VERSION \"" + version + "\" format invalid.";
std::string e = R"(VERSION ")" + version + R"(" format invalid.)";
this->Makefile->IssueMessage(MessageType::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;
cmPolicies::PolicyStatus const cmp0096 =
this->Makefile->GetPolicyStatus(cmPolicies::CMP0096);
constexpr std::size_t MAX_VERSION_COMPONENTS = 4u;
std::string version_string;
std::array<std::string, MAX_VERSION_COMPONENTS> version_components;
if (cmp0096 == cmPolicies::OLD || cmp0096 == cmPolicies::WARN) {
char vb[MAX_VERSION_COMPONENTS][std::numeric_limits<unsigned>::digits10];
unsigned v[MAX_VERSION_COMPONENTS] = { 0, 0, 0, 0 };
const int vc = std::sscanf(version.c_str(), "%u.%u.%u.%u", &v[0], &v[1],
&v[2], &v[3]);
for (auto i = 0u; i < MAX_VERSION_COMPONENTS; ++i) {
if (int(i) < vc) {
std::sprintf(vb[i], "%u", v[i]);
version_string += &"."[std::size_t(i == 0)];
version_string += vb[i];
version_components[i] = vb[i];
} else {
vb[i][0] = '\x00';
}
}
} else {
// The regex above verified that we have a .-separated string of
// non-negative integer components. Keep the original string.
version_string = std::move(version);
// Split the integer components.
auto components = cmSystemTools::SplitString(version_string, '.');
for (auto i = 0u; i < components.size(); ++i) {
version_components[i] = std::move(components[i]);
}
}
std::string vv;
vv = projectName + "_VERSION";
this->Makefile->AddDefinition("PROJECT_VERSION", vs.c_str());
this->Makefile->AddDefinition(vv, vs.c_str());
this->Makefile->AddDefinition("PROJECT_VERSION", version_string.c_str());
this->Makefile->AddDefinition(vv, version_string.c_str());
vv = projectName + "_VERSION_MAJOR";
this->Makefile->AddDefinition("PROJECT_VERSION_MAJOR", vb[0]);
this->Makefile->AddDefinition(vv, vb[0]);
this->Makefile->AddDefinition("PROJECT_VERSION_MAJOR",
version_components[0].c_str());
this->Makefile->AddDefinition(vv, version_components[0].c_str());
vv = projectName + "_VERSION_MINOR";
this->Makefile->AddDefinition("PROJECT_VERSION_MINOR", vb[1]);
this->Makefile->AddDefinition(vv, vb[1]);
this->Makefile->AddDefinition("PROJECT_VERSION_MINOR",
version_components[1].c_str());
this->Makefile->AddDefinition(vv, version_components[1].c_str());
vv = projectName + "_VERSION_PATCH";
this->Makefile->AddDefinition("PROJECT_VERSION_PATCH", vb[2]);
this->Makefile->AddDefinition(vv, vb[2]);
this->Makefile->AddDefinition("PROJECT_VERSION_PATCH",
version_components[2].c_str());
this->Makefile->AddDefinition(vv, version_components[2].c_str());
vv = projectName + "_VERSION_TWEAK";
this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK", vb[3]);
this->Makefile->AddDefinition(vv, vb[3]);
this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK",
version_components[3].c_str());
this->Makefile->AddDefinition(vv, version_components[3].c_str());
// Also, try set top level variables
TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION", vs.c_str());
TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MAJOR", vb[0]);
TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MINOR", vb[1]);
TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_PATCH", vb[2]);
TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_TWEAK", vb[3]);
TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION", version_string.c_str());
TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MAJOR",
version_components[0].c_str());
TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MINOR",
version_components[1].c_str());
TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_PATCH",
version_components[2].c_str());
TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_TWEAK",
version_components[3].c_str());
} else if (cmp0048 != cmPolicies::OLD) {
// Set project VERSION variables to empty
std::vector<std::string> vv;
vv.emplace_back("PROJECT_VERSION");
vv.emplace_back("PROJECT_VERSION_MAJOR");
vv.emplace_back("PROJECT_VERSION_MINOR");
vv.emplace_back("PROJECT_VERSION_PATCH");
vv.emplace_back("PROJECT_VERSION_TWEAK");
vv.push_back(projectName + "_VERSION");
vv.push_back(projectName + "_VERSION_MAJOR");
vv.push_back(projectName + "_VERSION_MINOR");
vv.push_back(projectName + "_VERSION_PATCH");
vv.push_back(projectName + "_VERSION_TWEAK");
std::vector<std::string> vv = { "PROJECT_VERSION",
"PROJECT_VERSION_MAJOR",
"PROJECT_VERSION_MINOR",
"PROJECT_VERSION_PATCH",
"PROJECT_VERSION_TWEAK",
projectName + "_VERSION",
projectName + "_VERSION_MAJOR",
projectName + "_VERSION_MINOR",
projectName + "_VERSION_PATCH",
projectName + "_VERSION_TWEAK" };
if (this->Makefile->IsRootMakefile()) {
vv.emplace_back("CMAKE_PROJECT_VERSION");
vv.emplace_back("CMAKE_PROJECT_VERSION_MAJOR");
@@ -287,7 +307,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
}
std::string vw;
for (std::string const& i : vv) {
const char* v = this->Makefile->GetDefinition(i);
const char* const v = this->Makefile->GetDefinition(i);
if (v && *v) {
if (cmp0048 == cmPolicies::WARN) {
if (!injectedProjectCommand) {
@@ -319,8 +339,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
if (languages.empty()) {
// if no language is specified do c and c++
languages.emplace_back("C");
languages.emplace_back("CXX");
languages = { "C", "CXX" };
}
this->Makefile->EnableLanguage(languages, false);
@@ -337,7 +356,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
bool cmProjectCommand::IncludeByVariable(const std::string& variable)
{
const char* include = this->Makefile->GetDefinition(variable);
const char* const include = this->Makefile->GetDefinition(variable);
if (!include) {
return true;
}

View File

@@ -1,9 +1,4 @@
macro(print_versions name)
foreach(v "" _MAJOR _MINOR _PATCH _TWEAK)
message(STATUS "PROJECT_VERSION${v}='${PROJECT_VERSION${v}}'")
message(STATUS "${name}_VERSION${v}='${${name}_VERSION${v}}'")
endforeach()
endmacro()
include(PrintVersions.cmake)
cmake_policy(SET CMP0048 NEW)

View File

@@ -0,0 +1,30 @@
-- PROJECT_VERSION='2019.07.06'
-- DateVersion_VERSION='2019.07.06'
-- PROJECT_VERSION_MAJOR='2019'
-- DateVersion_VERSION_MAJOR='2019'
-- PROJECT_VERSION_MINOR='07'
-- DateVersion_VERSION_MINOR='07'
-- PROJECT_VERSION_PATCH='06'
-- DateVersion_VERSION_PATCH='06'
-- PROJECT_VERSION_TWEAK=''
-- DateVersion_VERSION_TWEAK=''
-- PROJECT_VERSION='4294967297'
-- LongVersion_VERSION='4294967297'
-- PROJECT_VERSION_MAJOR='4294967297'
-- LongVersion_VERSION_MAJOR='4294967297'
-- PROJECT_VERSION_MINOR=''
-- LongVersion_VERSION_MINOR=''
-- PROJECT_VERSION_PATCH=''
-- LongVersion_VERSION_PATCH=''
-- PROJECT_VERSION_TWEAK=''
-- LongVersion_VERSION_TWEAK=''
-- PROJECT_VERSION='0009999999999.0009999999999.0009999999999.0009999999999'
-- VeryLongVersion_VERSION='0009999999999.0009999999999.0009999999999.0009999999999'
-- PROJECT_VERSION_MAJOR='0009999999999'
-- VeryLongVersion_VERSION_MAJOR='0009999999999'
-- PROJECT_VERSION_MINOR='0009999999999'
-- VeryLongVersion_VERSION_MINOR='0009999999999'
-- PROJECT_VERSION_PATCH='0009999999999'
-- VeryLongVersion_VERSION_PATCH='0009999999999'
-- PROJECT_VERSION_TWEAK='0009999999999'
-- VeryLongVersion_VERSION_TWEAK='0009999999999'

View File

@@ -0,0 +1,6 @@
cmake_policy(SET CMP0048 NEW)
cmake_policy(SET CMP0096 NEW)
include(CMP0096-common.cmake)
project(VeryLongVersion VERSION 0009999999999.0009999999999.0009999999999.0009999999999 LANGUAGES NONE)
print_versions(VeryLongVersion)

View File

@@ -0,0 +1,20 @@
-- PROJECT_VERSION='2019.7.6'
-- DateVersion_VERSION='2019.7.6'
-- PROJECT_VERSION_MAJOR='2019'
-- DateVersion_VERSION_MAJOR='2019'
-- PROJECT_VERSION_MINOR='7'
-- DateVersion_VERSION_MINOR='7'
-- PROJECT_VERSION_PATCH='6'
-- DateVersion_VERSION_PATCH='6'
-- PROJECT_VERSION_TWEAK=''
-- DateVersion_VERSION_TWEAK=''
-- PROJECT_VERSION='(1|4294967295)'
-- LongVersion_VERSION='(1|4294967295)'
-- PROJECT_VERSION_MAJOR='(1|4294967295)'
-- LongVersion_VERSION_MAJOR='(1|4294967295)'
-- PROJECT_VERSION_MINOR=''
-- LongVersion_VERSION_MINOR=''
-- PROJECT_VERSION_PATCH=''
-- LongVersion_VERSION_PATCH=''
-- PROJECT_VERSION_TWEAK=''
-- LongVersion_VERSION_TWEAK=''

View File

@@ -0,0 +1,3 @@
cmake_policy(SET CMP0048 NEW)
cmake_policy(SET CMP0096 OLD)
include(CMP0096-common.cmake)

View File

@@ -0,0 +1,20 @@
-- PROJECT_VERSION='2019.7.6'
-- DateVersion_VERSION='2019.7.6'
-- PROJECT_VERSION_MAJOR='2019'
-- DateVersion_VERSION_MAJOR='2019'
-- PROJECT_VERSION_MINOR='7'
-- DateVersion_VERSION_MINOR='7'
-- PROJECT_VERSION_PATCH='6'
-- DateVersion_VERSION_PATCH='6'
-- PROJECT_VERSION_TWEAK=''
-- DateVersion_VERSION_TWEAK=''
-- PROJECT_VERSION='(1|4294967295)'
-- LongVersion_VERSION='(1|4294967295)'
-- PROJECT_VERSION_MAJOR='(1|4294967295)'
-- LongVersion_VERSION_MAJOR='(1|4294967295)'
-- PROJECT_VERSION_MINOR=''
-- LongVersion_VERSION_MINOR=''
-- PROJECT_VERSION_PATCH=''
-- LongVersion_VERSION_PATCH=''
-- PROJECT_VERSION_TWEAK=''
-- LongVersion_VERSION_TWEAK=''

View File

@@ -0,0 +1,3 @@
cmake_policy(SET CMP0048 NEW)
include(CMP0096-common.cmake)

View File

@@ -0,0 +1,9 @@
include(PrintVersions.cmake)
# Test leading zeros motivating this policy.
project(DateVersion VERSION 2019.07.06 LANGUAGES NONE)
print_versions(DateVersion)
# Overflow version component in OLD behavior.
project(LongVersion VERSION 4294967297 #[[ uint32_max + 2 ]] LANGUAGES NONE)
print_versions(LongVersion)

View File

@@ -0,0 +1,6 @@
macro(print_versions name)
foreach(v "" _MAJOR _MINOR _PATCH _TWEAK)
message(STATUS "PROJECT_VERSION${v}='${PROJECT_VERSION${v}}'")
message(STATUS "${name}_VERSION${v}='${${name}_VERSION${v}}'")
endforeach()
endmacro()

View File

@@ -27,3 +27,7 @@ run_cmake(CMP0048-OLD)
run_cmake(CMP0048-OLD-VERSION)
run_cmake(CMP0048-WARN)
run_cmake(CMP0048-NEW)
run_cmake(CMP0096-WARN)
run_cmake(CMP0096-OLD)
run_cmake(CMP0096-NEW)