1# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2# file Copyright.txt or https://cmake.org/licensing for details.
3
4#[=======================================================================[.rst:
5CMakeDependentOption
6--------------------
7
8Macro to provide an option dependent on other options.
9
10This macro presents an option to the user only if a set of other
11conditions are true.
12
13.. command:: cmake_dependent_option
14
15  .. code-block:: cmake
16
17    cmake_dependent_option(<option> "<help_text>" <value> <depends> <force>)
18
19  Makes ``<option>`` available to the user if ``<depends>`` is true. When
20  ``<option>`` is available, the given ``<help_text>`` and initial ``<value>``
21  are used. If the ``<depends>`` condition is not true, ``<option>`` will not be
22  presented and will always have the value given by ``<force>``. Any value set by
23  the user is preserved for when the option is presented again. In case ``<depends>``
24  is a :ref:`semicolon-separated list <CMake Language Lists>`, all elements must
25  be true in order to initialize ``<option>`` with ``<value>``.
26
27Example invocation:
28
29.. code-block:: cmake
30
31  cmake_dependent_option(USE_FOO "Use Foo" ON "USE_BAR;NOT USE_ZOT" OFF)
32
33If ``USE_BAR`` is true and ``USE_ZOT`` is false, this provides an option called
34``USE_FOO`` that defaults to ON. Otherwise, it sets ``USE_FOO`` to OFF and
35hides the option from the user. If the status of ``USE_BAR`` or ``USE_ZOT``
36ever changes, any value for the ``USE_FOO`` option is saved so that when the
37option is re-enabled it retains its old value.
38
39.. versionadded:: 3.22
40
41  Full :ref:`Condition Syntax` is now supported.  See policy :policy:`CMP0127`.
42
43#]=======================================================================]
44
45macro(CMAKE_DEPENDENT_OPTION option doc default depends force)
46  cmake_policy(GET CMP0127 _CDO_CMP0127
47    PARENT_SCOPE # undocumented, do not use outside of CMake
48    )
49  if(${option}_ISSET MATCHES "^${option}_ISSET$")
50    set(${option}_AVAILABLE 1)
51    if("x${_CDO_CMP0127}x" STREQUAL "xNEWx")
52      foreach(d ${depends})
53        cmake_language(EVAL CODE "
54          if (${d})
55          else()
56            set(${option}_AVAILABLE 0)
57          endif()"
58        )
59      endforeach()
60    else()
61      foreach(d ${depends})
62        string(REGEX REPLACE " +" ";" CMAKE_DEPENDENT_OPTION_DEP "${d}")
63        if(${CMAKE_DEPENDENT_OPTION_DEP})
64        else()
65          set(${option}_AVAILABLE 0)
66        endif()
67      endforeach()
68    endif()
69    if(${option}_AVAILABLE)
70      option(${option} "${doc}" "${default}")
71      set(${option} "${${option}}" CACHE BOOL "${doc}" FORCE)
72    else()
73      if(${option} MATCHES "^${option}$")
74      else()
75        set(${option} "${${option}}" CACHE INTERNAL "${doc}")
76      endif()
77      set(${option} ${force})
78    endif()
79  else()
80    set(${option} "${${option}_ISSET}")
81  endif()
82  if("x${_CDO_CMP0127}x" STREQUAL "xx" AND "x${depends}x" MATCHES "[^A-Za-z0-9_; ]")
83    cmake_policy(GET_WARNING CMP0127 _CDO_CMP0127_WARNING)
84    message(AUTHOR_WARNING "${_CDO_CMP0127_WARNING}")
85  endif()
86  unset(_CDO_CMP0127)
87endmacro()
88