1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
|
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file LICENSE.rst or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
CMakeDependentOption
--------------------
This module provides a command to define boolean options whose availability and
default values depend on specified conditions or other options. This helps
maintain a clean configuration interface by only displaying options that are
relevant to the current settings.
Load this module in a CMake project with:
.. code-block:: cmake
include(CMakeDependentOption)
Commands
^^^^^^^^
This module provides the following command:
.. command:: cmake_dependent_option
Provides a boolean option that depends on a set of conditions:
.. code-block:: cmake
cmake_dependent_option(<variable> <help> <value> <condition> <else-value>)
This command creates a boolean ``<variable>`` and makes it available to the
user in the GUI (such as :manual:`cmake-gui(1)` or :manual:`ccmake(1)`), if
a set of conditions evaluates to boolean true.
The arguments are:
``<variable>``
The name of a variable that stores the option value.
``<help>``
A brief description of the option. This string is typically a short line of
text and is displayed in the GUI.
``<value>``
Boolean value for the ``<variable>``, when ``<condition>`` evaluates to
boolean true.
``<condition>``
Specifies the conditions that determine whether ``<variable>`` is set and
visible in the GUI.
* If ``<condition>`` evaluates to boolean false, option is hidden from the
user in the GUI, and a local variable ``<variable>`` is set to
``<else-value>``.
* If ``<condition>`` evaluates to boolean true, a boolean cache variable
named ``<variable>`` is created with default ``<value>``, and option is
shown in the GUI, allowing the user to enable or disable it.
* If ``<condition>`` later evaluates to boolean false (on consecutive
configuration run), option is hidden from the user in the GUI and the
``<variable>`` type is changed to an internal cache variable. In that
case a local variable of the same name is set to ``<else-value>``.
* If ``<condition>`` becomes true again in consecutive configuration runs,
the user's previously set value is preserved.
The ``<condition>`` argument can be:
* A single condition (such as a variable name).
* A :ref:`semicolon-separated list <CMake Language Lists>` of multiple
conditions.
* .. versionadded:: 3.22
A full :ref:`Condition Syntax` as used in an ``if(<condition>)`` clause.
See policy :policy:`CMP0127`. This enables using entire condition
syntax (such as grouping conditions with parens and similar).
``<else-value>``
The value assigned to a local variable named ``<variable>``, when
``<condition>`` evaluates to boolean false.
Examples
^^^^^^^^
Example: Basic Usage
""""""""""""""""""""
Using this module in a project to conditionally set an option:
.. code-block:: cmake
:caption: ``CMakeLists.txt``
include(CMakeDependentOption)
cmake_dependent_option(USE_SSL_GNUTLS "Use GnuTLS for SSL" ON USE_SSL OFF)
Example: Enabling/Disabling Dependent Option
""""""""""""""""""""""""""""""""""""""""""""
Extending the previous example, this demonstrates how the module allows
user-configurable options based on a condition during the configuration phase:
.. code-block:: cmake
:caption: ``CMakeLists.txt``
include(CMakeDependentOption)
option(USE_SSL "Enable SSL in the project" OFF)
cmake_dependent_option(USE_SSL_GNUTLS "Use GnuTLS for SSL" ON USE_SSL OFF)
message(STATUS "USE_SSL: ${USE_SSL}")
message(STATUS "USE_SSL_GNUTLS: ${USE_SSL_GNUTLS}")
On the first configuration run, a boolean cache variable ``USE_SSL`` is set to
OFF, and a local variable ``USE_SSL_GNUTLS`` is set to OFF:
.. code-block:: console
$ cmake -B build-dir
-- USE_SSL: OFF
-- USE_SSL_GNUTLS: OFF
Running CMake with ``USE_SSL=ON`` sets both ``USE_SSL`` and ``USE_SSL_GNUTLS``
boolean cache variables to ON:
.. code-block:: console
$ cmake -B build-dir -D USE_SSL=ON
-- USE_SSL: ON
-- USE_SSL_GNUTLS: ON
On a subsequent configuration run with ``USE_SSL=OFF``, ``USE_SSL_GNUTLS``
follows suit. However, its value is preserved in the internal cache while being
overridden locally:
.. code-block:: console
$ cmake -B build-dir -D USE_SSL=OFF
-- USE_SSL: OFF
-- USE_SSL_GNUTLS: OFF
Example: Semicolon-separated List of Conditions
"""""""""""""""""""""""""""""""""""""""""""""""
The ``<condition>`` argument can also be a semicolon-separated list of
conditions. In the following example, if the variable ``USE_BAR`` is ON and
variable ``USE_ZOT`` is OFF, the option ``USE_FOO`` is available and defaults to
ON. Otherwise, ``USE_FOO`` is set to OFF and hidden from the user.
If the values of ``USE_BAR`` or ``USE_ZOT`` change in the future configuration
runs, the previous value of ``USE_FOO`` is preserved so that when it becomes
available again, it retains its last set value.
.. code-block:: cmake
:caption: ``CMakeLists.txt``
include(CMakeDependentOption)
cmake_dependent_option(USE_FOO "Use Foo" ON "USE_BAR;NOT USE_ZOT" OFF)
Example: Full Condition Syntax
""""""""""""""""""""""""""""""
As of CMake 3.22, ``cmake_dependent_option()`` supports full condition syntax.
In fhe following example, if the condition evaluates to true, the option
``USE_FOO`` is available and set to ON. Otherwise, it is set to OFF and hidden
in the GUI. The value of ``USE_FOO`` is preserved across configuration runs,
similar to the previous example.
.. code-block:: cmake
:caption: ``CMakeLists.txt``
include(CMakeDependentOption)
cmake_dependent_option(USE_FOO "Use Foo" ON "USE_A AND (USE_B OR USE_C)" OFF)
Another example demonstrates how an option can be conditionally available based
on the target system:
.. code-block:: cmake
:caption: ``CMakeLists.txt``
include(CMakeDependentOption)
cmake_dependent_option(
ENABLE_FOO
"Enable feature Foo (this option is available when building for Windows)"
ON
[[CMAKE_SYSTEM_NAME STREQUAL "Windows"]]
OFF
)
See Also
^^^^^^^^
* The :command:`option` command to provide a boolean option that the user can
optionally select.
#]=======================================================================]
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)
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)
else()
if(${option} MATCHES "^${option}$")
else()
set(${option} "${${option}}" CACHE INTERNAL "${doc}")
endif()
set(${option} ${force})
endif()
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()
|