summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-policies.7.rst8
-rw-r--r--Help/policy/CMP0127.rst32
-rw-r--r--Help/release/dev/cmake_dependent_option_policy.rst6
-rw-r--r--Modules/CMakeDependentOption.cmake61
-rw-r--r--Source/cmPolicies.h5
-rw-r--r--Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-NEW-stdout.txt (renamed from Tests/RunCMake/CMakeDependentOption/Regex-stdout.txt)0
-rw-r--r--Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-NEW.cmake9
-rw-r--r--Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-WARN-stderr.txt9
-rw-r--r--Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-WARN-stdout.txt2
-rw-r--r--Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-WARN.cmake9
-rw-r--r--Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-NEW-stdout.txt1
-rw-r--r--Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-NEW.cmake7
-rw-r--r--Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-OLD-stdout.txt1
-rw-r--r--Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-OLD.cmake (renamed from Tests/RunCMake/CMakeDependentOption/Regex.cmake)2
-rw-r--r--Tests/RunCMake/CMakeDependentOption/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMakeDependentOption/Simple-CMP0127-OLD-stdout.txt1
-rw-r--r--Tests/RunCMake/CMakeDependentOption/Simple-CMP0127-OLD.cmake6
17 files changed, 143 insertions, 21 deletions
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index b9e3d45..0f0c0ab 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -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
=================================
diff --git a/Help/policy/CMP0127.rst b/Help/policy/CMP0127.rst
new file mode 100644
index 0000000..8560bbf
--- /dev/null
+++ b/Help/policy/CMP0127.rst
@@ -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
diff --git a/Help/release/dev/cmake_dependent_option_policy.rst b/Help/release/dev/cmake_dependent_option_policy.rst
new file mode 100644
index 0000000..c131170
--- /dev/null
+++ b/Help/release/dev/cmake_dependent_option_policy.rst
@@ -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`.
diff --git a/Modules/CMakeDependentOption.cmake b/Modules/CMakeDependentOption.cmake
index 96855d2..b7c478f 100644
--- a/Modules/CMakeDependentOption.cmake
+++ b/Modules/CMakeDependentOption.cmake
@@ -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()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index f7c0d25..a98e6c6 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -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) \
diff --git a/Tests/RunCMake/CMakeDependentOption/Regex-stdout.txt b/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-NEW-stdout.txt
index 15b56a1..15b56a1 100644
--- a/Tests/RunCMake/CMakeDependentOption/Regex-stdout.txt
+++ b/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-NEW-stdout.txt
diff --git a/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-NEW.cmake b/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-NEW.cmake
new file mode 100644
index 0000000..5a2b018
--- /dev/null
+++ b/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-NEW.cmake
@@ -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}'")
diff --git a/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-WARN-stderr.txt b/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-WARN-stderr.txt
new file mode 100644
index 0000000..b16e84b
--- /dev/null
+++ b/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-WARN-stderr.txt
@@ -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.$
diff --git a/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-WARN-stdout.txt b/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-WARN-stdout.txt
new file mode 100644
index 0000000..d89dbd3
--- /dev/null
+++ b/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-WARN-stdout.txt
@@ -0,0 +1,2 @@
+-- USE_FOO='OFF'
+-- USE_BAR='ON'
diff --git a/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-WARN.cmake b/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-WARN.cmake
new file mode 100644
index 0000000..00d440d
--- /dev/null
+++ b/Tests/RunCMake/CMakeDependentOption/Parentheses-CMP0127-WARN.cmake
@@ -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}'")
diff --git a/Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-NEW-stdout.txt b/Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-NEW-stdout.txt
new file mode 100644
index 0000000..15b56a1
--- /dev/null
+++ b/Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-NEW-stdout.txt
@@ -0,0 +1 @@
+-- USE_FOO='ON'
diff --git a/Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-NEW.cmake b/Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-NEW.cmake
new file mode 100644
index 0000000..e92c1e6
--- /dev/null
+++ b/Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-NEW.cmake
@@ -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}'")
diff --git a/Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-OLD-stdout.txt b/Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-OLD-stdout.txt
new file mode 100644
index 0000000..15b56a1
--- /dev/null
+++ b/Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-OLD-stdout.txt
@@ -0,0 +1 @@
+-- USE_FOO='ON'
diff --git a/Tests/RunCMake/CMakeDependentOption/Regex.cmake b/Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-OLD.cmake
index 8342a01..81df003 100644
--- a/Tests/RunCMake/CMakeDependentOption/Regex.cmake
+++ b/Tests/RunCMake/CMakeDependentOption/Regex-CMP0127-OLD.cmake
@@ -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}'")
diff --git a/Tests/RunCMake/CMakeDependentOption/RunCMakeTest.cmake b/Tests/RunCMake/CMakeDependentOption/RunCMakeTest.cmake
index e1045f2..61e046f 100644
--- a/Tests/RunCMake/CMakeDependentOption/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMakeDependentOption/RunCMakeTest.cmake
@@ -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)
diff --git a/Tests/RunCMake/CMakeDependentOption/Simple-CMP0127-OLD-stdout.txt b/Tests/RunCMake/CMakeDependentOption/Simple-CMP0127-OLD-stdout.txt
new file mode 100644
index 0000000..15b56a1
--- /dev/null
+++ b/Tests/RunCMake/CMakeDependentOption/Simple-CMP0127-OLD-stdout.txt
@@ -0,0 +1 @@
+-- USE_FOO='ON'
diff --git a/Tests/RunCMake/CMakeDependentOption/Simple-CMP0127-OLD.cmake b/Tests/RunCMake/CMakeDependentOption/Simple-CMP0127-OLD.cmake
new file mode 100644
index 0000000..6db2128
--- /dev/null
+++ b/Tests/RunCMake/CMakeDependentOption/Simple-CMP0127-OLD.cmake
@@ -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}'")