mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-31 02:39:48 -06:00
@@ -11,6 +11,7 @@ Synopsis
|
||||
project(<PROJECT-NAME> [<language-name>...])
|
||||
project(<PROJECT-NAME>
|
||||
[VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
|
||||
[COMPAT_VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
|
||||
[DESCRIPTION <project-description-string>]
|
||||
[HOMEPAGE_URL <url-string>]
|
||||
[LANGUAGES <language-name>...])
|
||||
@@ -86,6 +87,24 @@ The options are:
|
||||
``CMakeLists.txt``, then the version is also stored in the variable
|
||||
:variable:`CMAKE_PROJECT_VERSION`.
|
||||
|
||||
``COMPAT_VERSION <version>``
|
||||
.. note::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
|
||||
|
||||
Optional; requires ``VERSION`` also be set.
|
||||
|
||||
Takes a ``<version>`` argument composed of non-negative integer components,
|
||||
i.e. ``<major>[.<minor>[.<patch>[.<tweak>]]]``,
|
||||
and sets the variables
|
||||
|
||||
* :variable:`PROJECT_COMPAT_VERSION`,
|
||||
:variable:`<PROJECT-NAME>_COMPAT_VERSION`
|
||||
|
||||
When the ``project()`` command is called from the top-level
|
||||
``CMakeLists.txt``, then the compatibility version is also stored in the
|
||||
variable :variable:`CMAKE_PROJECT_COMPAT_VERSION`.
|
||||
|
||||
``DESCRIPTION <project-description-string>``
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
@@ -105,6 +105,7 @@ Variables that Provide Information
|
||||
/variable/CMAKE_PROJECT_VERSION_MINOR
|
||||
/variable/CMAKE_PROJECT_VERSION_PATCH
|
||||
/variable/CMAKE_PROJECT_VERSION_TWEAK
|
||||
/variable/CMAKE_PROJECT_COMPAT_VERSION
|
||||
/variable/CMAKE_RANLIB
|
||||
/variable/CMAKE_ROOT
|
||||
/variable/CMAKE_RULE_MESSAGES
|
||||
@@ -161,6 +162,7 @@ Variables that Provide Information
|
||||
/variable/PROJECT-NAME_VERSION_MINOR
|
||||
/variable/PROJECT-NAME_VERSION_PATCH
|
||||
/variable/PROJECT-NAME_VERSION_TWEAK
|
||||
/variable/PROJECT-NAME_COMPAT_VERSION
|
||||
/variable/PROJECT_BINARY_DIR
|
||||
/variable/PROJECT_DESCRIPTION
|
||||
/variable/PROJECT_HOMEPAGE_URL
|
||||
@@ -172,6 +174,7 @@ Variables that Provide Information
|
||||
/variable/PROJECT_VERSION_MINOR
|
||||
/variable/PROJECT_VERSION_PATCH
|
||||
/variable/PROJECT_VERSION_TWEAK
|
||||
/variable/PROJECT_COMPAT_VERSION
|
||||
|
||||
Variables that Change Behavior
|
||||
==============================
|
||||
|
||||
6
Help/release/dev/project-compat-version.rst
Normal file
6
Help/release/dev/project-compat-version.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
project-compat-version
|
||||
----------------------
|
||||
|
||||
* The :command:`project` command now has experimental support for the
|
||||
``COMPAT_VERSION`` keyword, gated by
|
||||
``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
|
||||
39
Help/variable/CMAKE_PROJECT_COMPAT_VERSION.rst
Normal file
39
Help/variable/CMAKE_PROJECT_COMPAT_VERSION.rst
Normal file
@@ -0,0 +1,39 @@
|
||||
CMAKE_PROJECT_COMPAT_VERSION
|
||||
----------------------------
|
||||
|
||||
.. note::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
|
||||
|
||||
The compatibility version of the top level project.
|
||||
|
||||
This variable holds the compatibility version of the project as specified in the
|
||||
top level CMakeLists.txt file by a :command:`project` command. In the event
|
||||
that the top level CMakeLists.txt contains multiple :command:`project` calls,
|
||||
the most recently called one from that top level CMakeLists.txt will determine
|
||||
the value that ``CMAKE_PROJECT_COMPAT_VERSION`` contains. For example, consider
|
||||
the following top level CMakeLists.txt:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 4.1)
|
||||
project(First VERSION 9.0 COMPAT_VERSION 1.2.3)
|
||||
project(Second VERSION 9.0 COMPAT_VERSION 3.4.5)
|
||||
add_subdirectory(sub)
|
||||
project(Third VERSION 9.0 COMPAT_VERSION 6.7.8)
|
||||
|
||||
And ``sub/CMakeLists.txt`` with the following contents:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
project(SubProj VERSION 2.0 COMPAT_VERSION 1.0)
|
||||
message("CMAKE_PROJECT_VERSION = ${CMAKE_PROJECT_VERSION}")
|
||||
|
||||
The most recently seen :command:`project` command from the top level
|
||||
CMakeLists.txt would be ``project(Second ...)``, so this will print::
|
||||
|
||||
CMAKE_PROJECT_COMPAT_VERSION = 3.4.5
|
||||
|
||||
To obtain the version from the most recent call to :command:`project` in
|
||||
the current directory scope or above, see the :variable:`PROJECT_COMPAT_VERSION`
|
||||
variable.
|
||||
9
Help/variable/PROJECT-NAME_COMPAT_VERSION.rst
Normal file
9
Help/variable/PROJECT-NAME_COMPAT_VERSION.rst
Normal file
@@ -0,0 +1,9 @@
|
||||
<PROJECT-NAME>_COMPAT_VERSION
|
||||
-----------------------------
|
||||
|
||||
.. note::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
|
||||
|
||||
Value given to the ``COMPAT_VERSION`` option of the most recent call to the
|
||||
:command:`project` command with project name ``<PROJECT-NAME>``, if any.
|
||||
10
Help/variable/PROJECT_COMPAT_VERSION.rst
Normal file
10
Help/variable/PROJECT_COMPAT_VERSION.rst
Normal file
@@ -0,0 +1,10 @@
|
||||
PROJECT_COMPAT_VERSION
|
||||
----------------------
|
||||
|
||||
.. note::
|
||||
|
||||
Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
|
||||
|
||||
Value given to the ``COMPAT_VERSION`` option of the most recent call to the
|
||||
:command:`project` command, if any. To obtain the compatibility version of the
|
||||
top level project, see the :variable:`CMAKE_PROJECT_COMPAT_VERSION` variable.
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "cmArgumentParser.h"
|
||||
#include "cmArgumentParserTypes.h"
|
||||
#include "cmExecutionStatus.h"
|
||||
#include "cmExperimental.h"
|
||||
#include "cmList.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
@@ -36,6 +37,7 @@ struct ProjectArguments : ArgumentParser::ParseResult
|
||||
{
|
||||
cm::optional<std::string> ProjectName;
|
||||
cm::optional<std::string> Version;
|
||||
cm::optional<std::string> CompatVersion;
|
||||
cm::optional<std::string> Description;
|
||||
cm::optional<std::string> HomepageURL;
|
||||
cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Languages;
|
||||
@@ -61,22 +63,30 @@ bool cmProjectCommand(std::vector<std::string> const& args,
|
||||
std::vector<cm::string_view> missingValueKeywords;
|
||||
std::vector<cm::string_view> parsedKeywords;
|
||||
ProjectArguments prArgs;
|
||||
ProjectArgumentParser{}
|
||||
.BindKeywordMissingValue(missingValueKeywords)
|
||||
ProjectArgumentParser parser;
|
||||
parser.BindKeywordMissingValue(missingValueKeywords)
|
||||
.BindParsedKeywords(parsedKeywords)
|
||||
.Bind(0, prArgs.ProjectName)
|
||||
.Bind("VERSION"_s, prArgs.Version)
|
||||
.Bind("DESCRIPTION"_s, prArgs.Description)
|
||||
.Bind("HOMEPAGE_URL"_s, prArgs.HomepageURL)
|
||||
.Bind("LANGUAGES"_s, prArgs.Languages)
|
||||
.Parse(args, &unparsedArgs, 0);
|
||||
.Bind("LANGUAGES"_s, prArgs.Languages);
|
||||
|
||||
cmMakefile& mf = status.GetMakefile();
|
||||
bool enableCompatVersion = cmExperimental::HasSupportEnabled(
|
||||
mf, cmExperimental::Feature::ExportPackageInfo);
|
||||
|
||||
if (enableCompatVersion) {
|
||||
parser.Bind("COMPAT_VERSION"_s, prArgs.CompatVersion);
|
||||
}
|
||||
|
||||
parser.Parse(args, &unparsedArgs, 0);
|
||||
|
||||
if (!prArgs.ProjectName) {
|
||||
status.SetError("PROJECT called with incorrect number of arguments");
|
||||
return false;
|
||||
}
|
||||
|
||||
cmMakefile& mf = status.GetMakefile();
|
||||
if (mf.IsRootMakefile() &&
|
||||
!mf.GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) {
|
||||
mf.IssueMessage(
|
||||
@@ -168,13 +178,21 @@ bool cmProjectCommand(std::vector<std::string> const& args,
|
||||
prArgs.Languages->emplace_back("NONE");
|
||||
}
|
||||
|
||||
if (prArgs.CompatVersion && !prArgs.Version) {
|
||||
mf.IssueMessage(MessageType::FATAL_ERROR,
|
||||
"project with COMPAT_VERSION must also provide VERSION.");
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
return true;
|
||||
}
|
||||
|
||||
cmsys::RegularExpression vx(
|
||||
R"(^([0-9]+(\.[0-9]+(\.[0-9]+(\.[0-9]+)?)?)?)?$)");
|
||||
|
||||
constexpr std::size_t MAX_VERSION_COMPONENTS = 4u;
|
||||
std::string version_string;
|
||||
std::array<std::string, MAX_VERSION_COMPONENTS> version_components;
|
||||
|
||||
if (prArgs.Version) {
|
||||
cmsys::RegularExpression vx(
|
||||
R"(^([0-9]+(\.[0-9]+(\.[0-9]+(\.[0-9]+)?)?)?)?$)");
|
||||
if (!vx.find(*prArgs.Version)) {
|
||||
std::string e =
|
||||
R"(VERSION ")" + *prArgs.Version + R"(" format invalid.)";
|
||||
@@ -215,19 +233,41 @@ bool cmProjectCommand(std::vector<std::string> const& args,
|
||||
}
|
||||
}
|
||||
|
||||
auto create_variables = [&](cm::string_view var, std::string const& val) {
|
||||
if (prArgs.CompatVersion) {
|
||||
if (!vx.find(*prArgs.CompatVersion)) {
|
||||
std::string e =
|
||||
R"(COMPAT_VERSION ")" + *prArgs.CompatVersion + R"(" format invalid.)";
|
||||
mf.IssueMessage(MessageType::FATAL_ERROR, e);
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cmSystemTools::VersionCompareGreater(*prArgs.CompatVersion,
|
||||
*prArgs.Version)) {
|
||||
mf.IssueMessage(MessageType::FATAL_ERROR,
|
||||
"COMPAT_VERSION must be less than or equal to VERSION");
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
auto createVariables = [&](cm::string_view var, std::string const& val) {
|
||||
mf.AddDefinition(cmStrCat("PROJECT_"_s, var), val);
|
||||
mf.AddDefinition(cmStrCat(*prArgs.ProjectName, "_"_s, var), val);
|
||||
TopLevelCMakeVarCondSet(mf, cmStrCat("CMAKE_PROJECT_"_s, var), val);
|
||||
};
|
||||
|
||||
create_variables("VERSION"_s, version_string);
|
||||
create_variables("VERSION_MAJOR"_s, version_components[0]);
|
||||
create_variables("VERSION_MINOR"_s, version_components[1]);
|
||||
create_variables("VERSION_PATCH"_s, version_components[2]);
|
||||
create_variables("VERSION_TWEAK"_s, version_components[3]);
|
||||
create_variables("DESCRIPTION"_s, prArgs.Description.value_or(""));
|
||||
create_variables("HOMEPAGE_URL"_s, prArgs.HomepageURL.value_or(""));
|
||||
createVariables("VERSION"_s, version_string);
|
||||
createVariables("VERSION_MAJOR"_s, version_components[0]);
|
||||
createVariables("VERSION_MINOR"_s, version_components[1]);
|
||||
createVariables("VERSION_PATCH"_s, version_components[2]);
|
||||
createVariables("VERSION_TWEAK"_s, version_components[3]);
|
||||
createVariables("DESCRIPTION"_s, prArgs.Description.value_or(""));
|
||||
createVariables("HOMEPAGE_URL"_s, prArgs.HomepageURL.value_or(""));
|
||||
|
||||
if (enableCompatVersion) {
|
||||
createVariables("COMPAT_VERSION"_s, prArgs.CompatVersion.value_or(""));
|
||||
}
|
||||
|
||||
if (unparsedArgs.empty() && !prArgs.Languages) {
|
||||
// if no language is specified do c and c++
|
||||
|
||||
3
Tests/RunCMake/project/ProjectCompatVersion-stdout.txt
Normal file
3
Tests/RunCMake/project/ProjectCompatVersion-stdout.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
-- PROJECT_COMPAT_VERSION=1.0.0
|
||||
-- CMAKE_PROJECT_COMPAT_VERSION=1.0.0
|
||||
-- ProjectCompatVersionTest_COMPAT_VERSION=1.0.0
|
||||
13
Tests/RunCMake/project/ProjectCompatVersion.cmake
Normal file
13
Tests/RunCMake/project/ProjectCompatVersion.cmake
Normal file
@@ -0,0 +1,13 @@
|
||||
project(ProjectCompatVersionTest VERSION 1.5.0 COMPAT_VERSION 1.0.0 LANGUAGES)
|
||||
if(NOT PROJECT_COMPAT_VERSION)
|
||||
message(FATAL_ERROR "PROJECT_COMPAT_VERSION expected to be set")
|
||||
endif()
|
||||
if(NOT CMAKE_PROJECT_COMPAT_VERSION)
|
||||
message(FATAL_ERROR "CMAKE_PROJECT_COMPAT_VERSION expected to be set")
|
||||
endif()
|
||||
if(NOT ProjectCompatVersionTest_COMPAT_VERSION)
|
||||
message(FATAL_ERROR "ProjectCompatVersionTest_COMPAT_VERSION expected to be set")
|
||||
endif()
|
||||
message(STATUS "PROJECT_COMPAT_VERSION=${PROJECT_COMPAT_VERSION}")
|
||||
message(STATUS "CMAKE_PROJECT_COMPAT_VERSION=${CMAKE_PROJECT_COMPAT_VERSION}")
|
||||
message(STATUS "ProjectCompatVersionTest_COMPAT_VERSION=${ProjectCompatVersionTest_COMPAT_VERSION}")
|
||||
1
Tests/RunCMake/project/ProjectCompatVersion2-result.txt
Normal file
1
Tests/RunCMake/project/ProjectCompatVersion2-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
1
Tests/RunCMake/project/ProjectCompatVersion2-stderr.txt
Normal file
1
Tests/RunCMake/project/ProjectCompatVersion2-stderr.txt
Normal file
@@ -0,0 +1 @@
|
||||
COMPAT_VERSION may be specified at most once.
|
||||
1
Tests/RunCMake/project/ProjectCompatVersion2.cmake
Normal file
1
Tests/RunCMake/project/ProjectCompatVersion2.cmake
Normal file
@@ -0,0 +1 @@
|
||||
project(ProjectCompatVersionTest VERSION 1.5.0 COMPAT_VERSION 1.0.0 COMPAT_VERSION 1.0.0 LANGUAGES)
|
||||
1
Tests/RunCMake/project/ProjectCompatVersionEqual.cmake
Normal file
1
Tests/RunCMake/project/ProjectCompatVersionEqual.cmake
Normal file
@@ -0,0 +1 @@
|
||||
project(ProjectCompatVersionTest VERSION 1.0.0 COMPAT_VERSION 1.0.0 LANGUAGES)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,4 @@
|
||||
CMake Error at ProjectCompatVersionInvalid.cmake:[0-9]+ \(project\):
|
||||
COMPAT_VERSION "NONE" format invalid.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)$
|
||||
1
Tests/RunCMake/project/ProjectCompatVersionInvalid.cmake
Normal file
1
Tests/RunCMake/project/ProjectCompatVersionInvalid.cmake
Normal file
@@ -0,0 +1 @@
|
||||
project(ProjectCompatVersionTest VERSION 1.5.0 COMPAT_VERSION NONE LANGUAGES)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1 @@
|
||||
project with COMPAT_VERSION must also provide VERSION.
|
||||
@@ -0,0 +1 @@
|
||||
project(ProjectCompatVersionTest COMPAT_VERSION 1.0.0 LANGUAGES)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1 @@
|
||||
COMPAT_VERSION must be less than or equal to VERSION
|
||||
1
Tests/RunCMake/project/ProjectCompatVersionNewer.cmake
Normal file
1
Tests/RunCMake/project/ProjectCompatVersionNewer.cmake
Normal file
@@ -0,0 +1 @@
|
||||
project(ProjectCompatVersionTest VERSION 1.0.0 COMPAT_VERSION 1.5.0 LANGUAGES)
|
||||
@@ -0,0 +1,2 @@
|
||||
COMPAT_VERSION keyword not followed by a value or was followed by a value
|
||||
that expanded to nothing.
|
||||
1
Tests/RunCMake/project/ProjectCompatVersionNoArg.cmake
Normal file
1
Tests/RunCMake/project/ProjectCompatVersionNoArg.cmake
Normal file
@@ -0,0 +1 @@
|
||||
project(ProjectCompatVersionTest VERSION 1.5.0 COMPAT_VERSION LANGUAGES)
|
||||
@@ -53,6 +53,19 @@ run_cmake(VersionMissingValueOkay)
|
||||
run_cmake(VersionTwice)
|
||||
run_cmake(VersionMax)
|
||||
|
||||
set(opts
|
||||
"-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO=b80be207-778e-46ba-8080-b23bba22639e"
|
||||
"-Wno-dev"
|
||||
)
|
||||
|
||||
run_cmake_with_options(ProjectCompatVersion ${opts})
|
||||
run_cmake_with_options(ProjectCompatVersion2 ${opts})
|
||||
run_cmake_with_options(ProjectCompatVersionEqual ${opts})
|
||||
run_cmake_with_options(ProjectCompatVersionInvalid ${opts})
|
||||
run_cmake_with_options(ProjectCompatVersionMissingVersion ${opts})
|
||||
run_cmake_with_options(ProjectCompatVersionNewer ${opts})
|
||||
run_cmake_with_options(ProjectCompatVersionNoArg ${opts})
|
||||
|
||||
run_cmake(CMP0048-NEW)
|
||||
|
||||
run_cmake(CMP0096-WARN)
|
||||
|
||||
Reference in New Issue
Block a user