Merge topic 'policy-version-var' into release-4.0 1a35351125 Add CMAKE_POLICY_VERSION_MINIMUM to help configure outdated projects d723198539 Help: De-duplicate policy version documentation e5d29e9e00 Help: Drop cmake_minimum_required pre-2.4 behavior Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: buildbot <buildbot@kitware.com> Merge-request: !10343
diff --git a/Help/command/POLICY_VERSION.txt b/Help/command/POLICY_VERSION.txt new file mode 100644 index 0000000..424849d --- /dev/null +++ b/Help/command/POLICY_VERSION.txt
@@ -0,0 +1,16 @@ +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, 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. +All policies known to the running version of CMake and introduced +in that version or earlier will be set to use ``NEW`` behavior. +All policies introduced in later versions will be unset (unless the +:variable:`CMAKE_POLICY_DEFAULT_CMP<NNNN>` variable sets a default). +This effectively requests behavior preferred as of a given CMake +version and tells newer CMake versions to warn about their new policies.
diff --git a/Help/command/cmake_minimum_required.rst b/Help/command/cmake_minimum_required.rst index 2833ed7..47e8e6b 100644 --- a/Help/command/cmake_minimum_required.rst +++ b/Help/command/cmake_minimum_required.rst
@@ -19,7 +19,7 @@ If the running version of CMake is lower than the ``<min>`` required version it will stop processing the project and report an error. The optional ``<policy_max>`` version, if specified, must be at least the -``<min>`` version and affects policy settings as described in `Policy Settings`_. +``<min>`` version and sets the `Policy Version`_. If the running version of CMake is older than 3.12, the extra ``...`` dots will be seen as version component separators, resulting in the ``...<max>`` part being ignored and preserving the pre-3.12 behavior @@ -48,38 +48,18 @@ calling scope, calling ``cmake_minimum_required()`` inside a function is generally discouraged. -.. _`Policy Settings`: +.. _`Policy Version`: -Policy Settings -^^^^^^^^^^^^^^^ +Policy Version +^^^^^^^^^^^^^^ -The ``cmake_minimum_required(VERSION)`` command implicitly invokes the -:command:`cmake_policy(VERSION)` command to specify that the current -project code is written for the given range of CMake versions. -All policies known to the running version of CMake and introduced -in the ``<min>`` (or ``<max>``, if specified) version or earlier will -be set to use ``NEW`` behavior. All policies introduced in later -versions will be unset (unless the -:variable:`CMAKE_POLICY_DEFAULT_CMP<NNNN>` variable sets a default). -This effectively requests behavior preferred as of a given CMake -version and tells newer CMake versions to warn about their new policies. - -When a ``<min>`` version higher than 2.4 is specified the command -implicitly invokes +``cmake_minimum_required(VERSION <min>[...<max>])`` implicitly invokes .. code-block:: cmake cmake_policy(VERSION <min>[...<max>]) -which sets CMake policies based on the range of versions specified. -When a ``<min>`` version 2.4 or lower is given the command implicitly -invokes - -.. code-block:: cmake - - cmake_policy(VERSION 2.4[...<max>]) - -which enables compatibility features for CMake 2.4 and lower. +.. include:: POLICY_VERSION.txt .. include:: DEPRECATED_POLICY_VERSIONS.txt
diff --git a/Help/command/cmake_policy.rst b/Help/command/cmake_policy.rst index 4a08c01..276e160 100644 --- a/Help/command/cmake_policy.rst +++ b/Help/command/cmake_policy.rst
@@ -39,14 +39,7 @@ component separators, resulting in the ``...<max>`` part being ignored and preserving the pre-3.12 behavior of basing policies on ``<min>``. -This specifies that the current CMake code is written for the given -range of CMake versions. All policies known to the running version of CMake -and introduced in the ``<min>`` (or ``<max>``, if specified) version -or earlier will be set to use ``NEW`` behavior. All policies -introduced in later versions will be unset (unless the -:variable:`CMAKE_POLICY_DEFAULT_CMP<NNNN>` variable sets a default). -This effectively requests behavior preferred as of a given CMake -version and tells newer CMake versions to warn about their new policies. +.. include:: POLICY_VERSION.txt Note that the :command:`cmake_minimum_required(VERSION)` command implicitly calls ``cmake_policy(VERSION)`` too.
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 200fc18..cbf8a92 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst
@@ -254,6 +254,7 @@ /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
diff --git a/Help/release/4.0.rst b/Help/release/4.0.rst index 80a55bf..b1102d5 100644 --- a/Help/release/4.0.rst +++ b/Help/release/4.0.rst
@@ -72,6 +72,10 @@ 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"
diff --git a/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst index d643fb8..5f47d4e 100644 --- a/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst +++ b/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst
@@ -22,3 +22,6 @@ * 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.
diff --git a/Help/variable/CMAKE_POLICY_VERSION_MINIMUM.rst b/Help/variable/CMAKE_POLICY_VERSION_MINIMUM.rst new file mode 100644 index 0000000..cf48ecf --- /dev/null +++ b/Help/variable/CMAKE_POLICY_VERSION_MINIMUM.rst
@@ -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.
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 9de978e..908a786 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx
@@ -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 @@ 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 @@ } 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; }
diff --git a/Tests/RunCMake/cmake_minimum_required/BeforeVersionRemoved-stderr.txt b/Tests/RunCMake/cmake_minimum_required/BeforeVersionRemoved-stderr.txt index 62145e6..f2f41af 100644 --- a/Tests/RunCMake/cmake_minimum_required/BeforeVersionRemoved-stderr.txt +++ b/Tests/RunCMake/cmake_minimum_required/BeforeVersionRemoved-stderr.txt
@@ -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\)$
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyBeforeVersionRemoved-stderr.txt b/Tests/RunCMake/cmake_minimum_required/PolicyBeforeVersionRemoved-stderr.txt index c9eba0f..bf4035a 100644 --- a/Tests/RunCMake/cmake_minimum_required/PolicyBeforeVersionRemoved-stderr.txt +++ b/Tests/RunCMake/cmake_minimum_required/PolicyBeforeVersionRemoved-stderr.txt
@@ -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\)$
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariable-stderr.txt b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariable-stderr.txt new file mode 100644 index 0000000..4f161bf --- /dev/null +++ b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariable-stderr.txt
@@ -0,0 +1,3 @@ +^CMAKE_MINIMUM_REQUIRED_VERSION='3\.1' +CMP0071='NEW' +CMP0072=''$
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariable.cmake b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariable.cmake new file mode 100644 index 0000000..553fc94 --- /dev/null +++ b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariable.cmake
@@ -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()
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad-result.txt b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad-result.txt
@@ -0,0 +1 @@ +1
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad-stderr.txt b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad-stderr.txt new file mode 100644 index 0000000..3a59bb7 --- /dev/null +++ b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad-stderr.txt
@@ -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\)$
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad.cmake b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad.cmake new file mode 100644 index 0000000..763997b --- /dev/null +++ b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad.cmake
@@ -0,0 +1,2 @@ +set(CMAKE_POLICY_VERSION_MINIMUM ...3.10) +cmake_minimum_required(VERSION 3.1...3.4)
diff --git a/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake b/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake index cd63093..d91f171 100644 --- a/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake +++ b/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
@@ -7,3 +7,5 @@ run_cmake(Range) run_cmake(RangeBad) run_cmake(Unknown) +run_cmake(PolicyVersionVariable) +run_cmake(PolicyVersionVariableBad)