Add CMAKE_POLICY_VERSION_MINIMUM to help configure outdated projects

Provide packagers and end users with a way to try configuring projects that
have not been updated to set their policy version to a supported level.

Closes: #26698
This commit is contained in:
Brad King 2025-02-13 12:37:32 -05:00
parent d723198539
commit 1a35351125
14 changed files with 86 additions and 2 deletions

View File

@ -2,7 +2,9 @@ This specifies that the current CMake code is written for the given range of
CMake versions, ``<min>[...<max>]``. It sets the "policy version" to:
* the range's ``<max>`` version, if specified, or to
* the ``<min>`` version.
* the ``<min>`` version, or to
* the value of the :variable:`CMAKE_POLICY_VERSION_MINIMUM` variable
if it is higher than the other two versions.
The policy version effectively requests behavior preferred as of a given CMake
version and tells newer CMake versions to warn about their new policies.

View File

@ -254,6 +254,7 @@ Variables that Change Behavior
/variable/CMAKE_MFC_FLAG
/variable/CMAKE_MODULE_PATH
/variable/CMAKE_POLICY_DEFAULT_CMPNNNN
/variable/CMAKE_POLICY_VERSION_MINIMUM
/variable/CMAKE_POLICY_WARNING_CMPNNNN
/variable/CMAKE_PREFIX_PATH
/variable/CMAKE_PROGRAM_PATH

View File

@ -72,6 +72,10 @@ Variables
to select runtime checks for compilers targeting the MSVC ABI.
See policy :policy:`CMP0184`.
* The :variable:`CMAKE_POLICY_VERSION_MINIMUM` variable was added to
help pacakgers and end users try to configure existing projects that
have not been updated to work with supported CMake versions.
* The :variable:`CMAKE_XCODE_SCHEME_LLDB_INIT_FILE` variable and corresponding
:prop_tgt:`XCODE_SCHEME_LLDB_INIT_FILE` target property were added to tell
the :generator:`Xcode` generator what to put in the scheme's "LLDB Init File"

View File

@ -22,3 +22,6 @@ not itself been updated:
* Projects may set this variable before a call to :command:`add_subdirectory`
that adds a third-party project in order to set its policies without
modifying third-party code.
See :variable:`CMAKE_POLICY_VERSION_MINIMUM` set policies to ``NEW``
based on the version of CMake that introduced them.

View File

@ -0,0 +1,23 @@
CMAKE_POLICY_VERSION_MINIMUM
----------------------------
.. versionadded:: 4.0
Specify a minimum :ref:`Policy Version` for a project without modifying
its calls to :command:`cmake_minimum_required(VERSION)` and
:command:`cmake_policy(VERSION)`.
This variable should not be set by a project in CMake code as a way to
set its own policy version. Use :command:`cmake_minimum_required(VERSION)`
and/or :command:`cmake_policy(VERSION)` for that. This variable is meant
to externally set policies for which a project has not itself been updated:
* Users running CMake may set this variable in the cache, e.g.,
``-DCMAKE_POLICY_VERSION_MINIMUM=3.5``, to try configuring a project
that has not been updated to set at least that policy version itself.
* Projects may set this variable before a call to :command:`add_subdirectory`
that adds a third-party project in order to set its policy version without
modifying third-party code.
See :variable:`CMAKE_POLICY_DEFAULT_CMP<NNNN>` to set individual policies.

View File

@ -15,6 +15,7 @@
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
#include "cmVersion.h"
static bool stringToId(char const* input, cmPolicies::PolicyID& pid)
@ -294,6 +295,30 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf, unsigned int majorVer,
unsigned int patchVer,
WarnCompat warnCompat)
{
cmValue varVer = mf->GetDefinition("CMAKE_POLICY_VERSION_MINIMUM");
if (!varVer.IsEmpty()) {
unsigned int varMajor = 0;
unsigned int varMinor = 0;
unsigned int varPatch = 0;
unsigned int varTweak = 0;
if (sscanf(varVer.GetCStr(), "%u.%u.%u.%u", &varMajor, &varMinor,
&varPatch, &varTweak) < 2) {
mf->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("Invalid CMAKE_POLICY_VERSION_MINIMUM value \"", varVer,
"\". "
"A numeric major.minor[.patch[.tweak]] must be given."));
return false;
}
if (varMajor > majorVer || (varMajor == majorVer && varMinor > minorVer) ||
(varMajor == majorVer && varMinor == minorVer &&
varPatch > patchVer)) {
majorVer = varMajor;
minorVer = varMinor;
patchVer = varPatch;
}
}
// Error on policy versions for which support has been removed.
if (majorVer < 3 || (majorVer == 3 && minorVer < 5)) {
if (IsFromLegacyInstallEXPORT(mf, majorVer, minorVer, patchVer)) {
@ -305,7 +330,9 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf, unsigned int majorVer,
} else {
mf->IssueMessage(MessageType::FATAL_ERROR,
"Compatibility with CMake < 3.5 has been removed "
"from CMake.\n" ADVICE_UPDATE_VERSION_ARGUMENT);
"from CMake.\n" ADVICE_UPDATE_VERSION_ARGUMENT "\n"
"Or, add -DCMAKE_POLICY_VERSION_MINIMUM=3.5 to try "
"configuring anyway.");
cmSystemTools::SetFatalErrorOccurred();
return false;
}

View File

@ -4,5 +4,7 @@
Update the VERSION argument <min> value\. Or, use the <min>\.\.\.<max> syntax
to tell CMake that the project requires at least <min> but has been updated
to work with policies introduced by <max> or earlier\.
Or, add -DCMAKE_POLICY_VERSION_MINIMUM=3\.5 to try configuring anyway\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)$

View File

@ -4,5 +4,7 @@
Update the VERSION argument <min> value\. Or, use the <min>\.\.\.<max> syntax
to tell CMake that the project requires at least <min> but has been updated
to work with policies introduced by <max> or earlier\.
Or, add -DCMAKE_POLICY_VERSION_MINIMUM=3\.5 to try configuring anyway\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)$

View File

@ -0,0 +1,3 @@
^CMAKE_MINIMUM_REQUIRED_VERSION='3\.1'
CMP0071='NEW'
CMP0072=''$

View File

@ -0,0 +1,7 @@
set(CMAKE_POLICY_VERSION_MINIMUM 3.10)
cmake_minimum_required(VERSION 3.1...3.4)
message("CMAKE_MINIMUM_REQUIRED_VERSION='${CMAKE_MINIMUM_REQUIRED_VERSION}'")
foreach(policy CMP0071 CMP0072)
cmake_policy(GET ${policy} status)
message("${policy}='${status}'")
endforeach()

View File

@ -0,0 +1,5 @@
^CMake Error at PolicyVersionVariableBad\.cmake:2 \(cmake_minimum_required\):
Invalid CMAKE_POLICY_VERSION_MINIMUM value "\.\.\.3\.10"\. A numeric
major\.minor\[\.patch\[\.tweak\]\] must be given\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)$

View File

@ -0,0 +1,2 @@
set(CMAKE_POLICY_VERSION_MINIMUM ...3.10)
cmake_minimum_required(VERSION 3.1...3.4)

View File

@ -7,3 +7,5 @@ run_cmake(BeforeVersionDeprecated)
run_cmake(Range)
run_cmake(RangeBad)
run_cmake(Unknown)
run_cmake(PolicyVersionVariable)
run_cmake(PolicyVersionVariableBad)