mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-02 03:39:43 -06:00
CMakeDependentOption: Introduce policy CMP0127 for full Condition Syntax
Fixes: #22303
This commit is contained in:
committed by
Brad King
parent
ed9abd9977
commit
059b90a0b4
@@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
|
||||
to determine whether to report an error on use of deprecated macros or
|
||||
functions.
|
||||
|
||||
Policies Introduced by CMake 3.22
|
||||
=================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
CMP0127: cmake_dependent_option() supports full Condition Syntax. </policy/CMP0127>
|
||||
|
||||
Policies Introduced by CMake 3.21
|
||||
=================================
|
||||
|
||||
|
||||
32
Help/policy/CMP0127.rst
Normal file
32
Help/policy/CMP0127.rst
Normal file
@@ -0,0 +1,32 @@
|
||||
CMP0127
|
||||
-------
|
||||
|
||||
:command:`cmake_dependent_option` supports full :ref:`Condition Syntax`.
|
||||
|
||||
The ``<depends>`` parameter accepts a :ref:`semicolon-separated list <CMake
|
||||
Language Lists>` of conditions. CMake 3.21 and lower evaluates each
|
||||
``condition`` as ``if(${condition})``, which does not properly handle
|
||||
conditions with nested paren groups. CMake 3.22 and above instead prefer
|
||||
to evaluate each ``condition`` as ``if(<condition>)``, where ``<condition>``
|
||||
is re-parsed as if literally written in a call to :command:`if`. This
|
||||
allows expressions like::
|
||||
|
||||
"A AND (B OR C)"
|
||||
|
||||
but requires expressions like::
|
||||
|
||||
"FOO MATCHES (UPPER|lower)"
|
||||
|
||||
to be re-written as::
|
||||
|
||||
"FOO MATCHES \"(UPPER|lower)\""
|
||||
|
||||
Policy ``CMP0127`` provides compatibility for projects that have not
|
||||
been updated to expect the new behavior.
|
||||
|
||||
This policy was introduced in CMake version 3.22. CMake version
|
||||
|release| warns when the policy is not set and uses ``OLD`` behavior.
|
||||
Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
|
||||
explicitly.
|
||||
|
||||
.. include:: DEPRECATED.txt
|
||||
6
Help/release/dev/cmake_dependent_option_policy.rst
Normal file
6
Help/release/dev/cmake_dependent_option_policy.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
cmake_dependent_option_policy
|
||||
-----------------------------
|
||||
|
||||
* The :module:`CMakeDependentOption` module :command:`cmake_dependent_option`
|
||||
macro now supports full :ref:`Condition Syntax`.
|
||||
See policy :policy:`CMP0127`.
|
||||
@@ -10,44 +10,62 @@ Macro to provide an option dependent on other options.
|
||||
This macro presents an option to the user only if a set of other
|
||||
conditions are true.
|
||||
|
||||
Usage:
|
||||
.. command:: cmake_dependent_option
|
||||
|
||||
.. code-block:: cmake
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_dependent_option(<option> "<help_text>" <value> <depends> <force>)
|
||||
cmake_dependent_option(<option> "<help_text>" <value> <depends> <force>)
|
||||
|
||||
Where ``<option>`` is available to the user if ``<depends>`` is true. When
|
||||
``<option>`` is available, the given ``<help_text>`` and initial ``<value>``
|
||||
are used. If the ``<depends>`` condition is not true, ``<option>`` will not be
|
||||
presented and will always have the value given by ``<force>``. Any value set by
|
||||
the user is preserved for when the option is presented again. Each element in
|
||||
the fourth parameter is evaluated as an if-condition, so
|
||||
:ref:`Condition Syntax` can be used.
|
||||
Makes ``<option>`` available to the user if ``<depends>`` is true. When
|
||||
``<option>`` is available, the given ``<help_text>`` and initial ``<value>``
|
||||
are used. If the ``<depends>`` condition is not true, ``<option>`` will not be
|
||||
presented and will always have the value given by ``<force>``. Any value set by
|
||||
the user is preserved for when the option is presented again. In case ``<depends>``
|
||||
is a :ref:`semicolon-separated list <CMake Language Lists>`, all elements must
|
||||
be true in order to initialize ``<option>`` with ``<value>``.
|
||||
|
||||
Example invocation:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_dependent_option(USE_FOO "Use Foo" ON
|
||||
"USE_BAR;NOT USE_ZOT" OFF)
|
||||
cmake_dependent_option(USE_FOO "Use Foo" ON "USE_BAR;NOT USE_ZOT" OFF)
|
||||
|
||||
If ``USE_BAR`` is true and ``USE_ZOT`` is false, this provides an option called
|
||||
``USE_FOO`` that defaults to ON. Otherwise, it sets ``USE_FOO`` to OFF and
|
||||
hides the option from the user. If the status of ``USE_BAR`` or ``USE_ZOT``
|
||||
ever changes, any value for the ``USE_FOO`` option is saved so that when the
|
||||
option is re-enabled it retains its old value.
|
||||
|
||||
.. versionadded:: 3.22
|
||||
|
||||
Full :ref:`Condition Syntax` is now supported. See policy :policy:`CMP0127`.
|
||||
|
||||
#]=======================================================================]
|
||||
|
||||
macro(CMAKE_DEPENDENT_OPTION option doc default depends force)
|
||||
cmake_policy(GET CMP0127 _CDO_CMP0127
|
||||
PARENT_SCOPE # undocumented, do not use outside of CMake
|
||||
)
|
||||
if(${option}_ISSET MATCHES "^${option}_ISSET$")
|
||||
set(${option}_AVAILABLE 1)
|
||||
foreach(d ${depends})
|
||||
string(REGEX REPLACE " +" ";" CMAKE_DEPENDENT_OPTION_DEP "${d}")
|
||||
if(${CMAKE_DEPENDENT_OPTION_DEP})
|
||||
else()
|
||||
set(${option}_AVAILABLE 0)
|
||||
endif()
|
||||
endforeach()
|
||||
if("x${_CDO_CMP0127}x" STREQUAL "xNEWx")
|
||||
foreach(d ${depends})
|
||||
cmake_language(EVAL CODE "
|
||||
if (${d})
|
||||
else()
|
||||
set(${option}_AVAILABLE 0)
|
||||
endif()"
|
||||
)
|
||||
endforeach()
|
||||
else()
|
||||
foreach(d ${depends})
|
||||
string(REGEX REPLACE " +" ";" CMAKE_DEPENDENT_OPTION_DEP "${d}")
|
||||
if(${CMAKE_DEPENDENT_OPTION_DEP})
|
||||
else()
|
||||
set(${option}_AVAILABLE 0)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
if(${option}_AVAILABLE)
|
||||
option(${option} "${doc}" "${default}")
|
||||
set(${option} "${${option}}" CACHE BOOL "${doc}" FORCE)
|
||||
@@ -61,4 +79,9 @@ macro(CMAKE_DEPENDENT_OPTION option doc default depends force)
|
||||
else()
|
||||
set(${option} "${${option}_ISSET}")
|
||||
endif()
|
||||
if("x${_CDO_CMP0127}x" STREQUAL "xx" AND "x${depends}x" MATCHES "[^A-Za-z0-9_; ]")
|
||||
cmake_policy(GET_WARNING CMP0127 _CDO_CMP0127_WARNING)
|
||||
message(AUTHOR_WARNING "${_CDO_CMP0127_WARNING}")
|
||||
endif()
|
||||
unset(_CDO_CMP0127)
|
||||
endmacro()
|
||||
|
||||
@@ -379,7 +379,10 @@ class cmMakefile;
|
||||
3, 21, 0, cmPolicies::WARN) \
|
||||
SELECT(POLICY, CMP0126, \
|
||||
"set(CACHE) does not remove a normal variable of the same name.", 3, \
|
||||
21, 0, cmPolicies::WARN)
|
||||
21, 0, cmPolicies::WARN) \
|
||||
SELECT(POLICY, CMP0127, \
|
||||
"cmake_dependent_option() supports full Condition Syntax.", 3, 22, \
|
||||
0, cmPolicies::WARN)
|
||||
|
||||
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
|
||||
#define CM_FOR_EACH_POLICY_ID(POLICY) \
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
include(CMakeDependentOption)
|
||||
|
||||
cmake_policy(SET CMP0127 NEW)
|
||||
|
||||
set(A 1)
|
||||
set(B 1)
|
||||
set(C 0)
|
||||
cmake_dependent_option(USE_FOO "Use Foo" ON "A AND (B OR C)" OFF)
|
||||
message(STATUS "USE_FOO='${USE_FOO}'")
|
||||
@@ -0,0 +1,9 @@
|
||||
^CMake Warning \(dev\) at [^
|
||||
]*/Modules/CMakeDependentOption.cmake:[0-9]+ \(message\):
|
||||
Policy CMP0127 is not set: cmake_dependent_option\(\) supports full Condition
|
||||
Syntax. Run "cmake --help-policy CMP0127" for policy details. Use the
|
||||
cmake_policy command to set the policy and suppress this warning.
|
||||
Call Stack \(most recent call first\):
|
||||
[^
|
||||
]*/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-WARN.cmake:[0-9]+ \(cmake_dependent_option\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.$
|
||||
@@ -0,0 +1,2 @@
|
||||
-- USE_FOO='OFF'
|
||||
-- USE_BAR='ON'
|
||||
@@ -0,0 +1,9 @@
|
||||
include(CMakeDependentOption)
|
||||
|
||||
set(A 1)
|
||||
set(B 1)
|
||||
set(C 0)
|
||||
cmake_dependent_option(USE_FOO "Use Foo" ON "A AND (B OR C)" OFF)
|
||||
message(STATUS "USE_FOO='${USE_FOO}'")
|
||||
cmake_dependent_option(USE_BAR "Use Bar" ON "A;B" OFF)
|
||||
message(STATUS "USE_BAR='${USE_BAR}'")
|
||||
@@ -0,0 +1 @@
|
||||
-- USE_FOO='ON'
|
||||
@@ -0,0 +1,7 @@
|
||||
include(CMakeDependentOption)
|
||||
|
||||
cmake_policy(SET CMP0127 NEW)
|
||||
|
||||
set(FOO "lower")
|
||||
cmake_dependent_option(USE_FOO "Use Foo" ON "FOO MATCHES \"(UPPER|lower)\"" OFF)
|
||||
message(STATUS "USE_FOO='${USE_FOO}'")
|
||||
@@ -0,0 +1 @@
|
||||
-- USE_FOO='ON'
|
||||
@@ -1,5 +1,7 @@
|
||||
include(CMakeDependentOption)
|
||||
|
||||
cmake_policy(SET CMP0127 OLD)
|
||||
|
||||
set(FOO "lower")
|
||||
cmake_dependent_option(USE_FOO "Use Foo" ON "FOO MATCHES (UPPER|lower)" OFF)
|
||||
message(STATUS "USE_FOO='${USE_FOO}'")
|
||||
@@ -1,3 +1,6 @@
|
||||
include(RunCMake)
|
||||
|
||||
run_cmake_script(Regex)
|
||||
run_cmake_script(Regex-CMP0127-NEW)
|
||||
run_cmake_script(Regex-CMP0127-OLD)
|
||||
run_cmake_script(Parentheses-CMP0127-NEW)
|
||||
run_cmake_script(Parentheses-CMP0127-WARN)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
-- USE_FOO='ON'
|
||||
@@ -0,0 +1,6 @@
|
||||
include(CMakeDependentOption)
|
||||
|
||||
set(A1 1)
|
||||
set(bb 1)
|
||||
cmake_dependent_option(USE_FOO "Use Foo" ON "A1;bb" OFF)
|
||||
message(STATUS "USE_FOO='${USE_FOO}'")
|
||||
Reference in New Issue
Block a user