| # 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 CMake 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. | |
| In CMake project mode, boolean cache variables are created as explained | |
| above. In CMake script mode, boolean variables are set instead. | |
| 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(ISSUE_WARNING CMP0127) | |
| endif() | |
| unset(_CDO_CMP0127) | |
| endmacro() |