Merge topic 'cuda_add_12.8_new_sm_support'
[kiteware-cmake.git] / Modules / CMakePushCheckState.cmake
blob96a2edce34dcb6e93b96840bdd9132d199c4b03a
1 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
4 include_guard(GLOBAL)
6 #[=======================================================================[.rst:
7 CMakePushCheckState
8 -------------------
10 This module provides macros for managing the state of variables that influence
11 how various CMake check commands (e.g., ``check_symbol_exists()``, etc.) are
12 performed.  These macros save, reset, and restore the following variables:
14 * ``CMAKE_REQUIRED_FLAGS``
15 * ``CMAKE_REQUIRED_DEFINITIONS``
16 * ``CMAKE_REQUIRED_INCLUDES``
17 * ``CMAKE_REQUIRED_LINK_OPTIONS``
18 * ``CMAKE_REQUIRED_LIBRARIES``
19 * ``CMAKE_REQUIRED_LINK_DIRECTORIES``
20 * ``CMAKE_REQUIRED_QUIET``
21 * ``CMAKE_EXTRA_INCLUDE_FILES``
23 Macros
24 ^^^^^^
26 .. command:: cmake_push_check_state
28   Saves (pushes) the current states of the above variables onto a stack.  This
29   is typically used to preserve the current configuration before making
30   temporary modifications for specific checks.
32   .. code-block:: cmake
34     cmake_push_check_state([RESET])
36   ``RESET``
37     When this option is specified, the macro not only saves the current states
38     of the listed variables but also resets them to empty, allowing them to be
39     reconfigured from a clean state.
41 .. command:: cmake_reset_check_state
43   Resets (clears) the contents of the variables listed above to empty states.
45   .. code-block:: cmake
47     cmake_reset_check_state()
49   This macro can be used, for example, when performing multiple sequential
50   checks that require entirely new configurations, ensuring no previous
51   configuration unintentionally carries over.
53 .. command:: cmake_pop_check_state
55   Restores the states of the variables listed above to their values at the time
56   of the most recent ``cmake_push_check_state()`` call.
58   .. code-block:: cmake
60     cmake_pop_check_state()
62   This macro is used to revert temporary changes made during a check.  To
63   prevent unexpected behavior, pair each ``cmake_push_check_state()`` with a
64   corresponding ``cmake_pop_check_state()``.
66 These macros are useful for scoped configuration, for example, in
67 :ref:`Find modules <Find Modules>` or when performing checks in a controlled
68 environment, ensuring that temporary modifications are isolated to the scope of
69 the check and do not propagate into other parts of the build system.
71 .. note::
73   Other CMake variables, such as ``CMAKE_<LANG>_FLAGS``, propagate to all checks
74   regardless of these macros, as those fundamental variables are designed to
75   influence the global state of the build system.
77 Examples
78 ^^^^^^^^
80 .. code-block:: cmake
82   include(CMakePushCheckState)
84   # Save and reset the current state
85   cmake_push_check_state(RESET)
87   # Perform check with specific compile definitions
88   set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
89   include(CheckSymbolExists)
90   check_symbol_exists(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE)
92   # Restore the original state
93   cmake_pop_check_state()
95 Variable states can be pushed onto the stack multiple times, allowing for nested
96 or sequential configurations.  Each ``cmake_pop_check_state()`` restores the
97 most recent pushed states.
99 .. code-block:: cmake
101   include(CMakePushCheckState)
103   # Save and reset the current state
104   cmake_push_check_state(RESET)
106   # Perform the first check with additional libraries
107   set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS})
108   include(CheckSymbolExists)
109   check_symbol_exists(dlopen "dlfcn.h" HAVE_DLOPEN)
111   # Save current state
112   cmake_push_check_state()
114   # Perform the second check with libraries and additional compile definitions
115   set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
116   check_symbol_exists(dladdr "dlfcn.h" HAVE_DLADDR)
118   message(STATUS "${CMAKE_REQUIRED_DEFINITIONS}")
119   # Output: -D_GNU_SOURCE
121   # Restore the previous state
122   cmake_pop_check_state()
124   message(STATUS "${CMAKE_REQUIRED_DEFINITIONS}")
125   # Output here is empty
127   # Reset variables to prepare for the next check
128   cmake_reset_check_state()
130   # Perform the next check only with additional compile definitions
131   set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
132   check_symbol_exists(dl_iterate_phdr "link.h" HAVE_DL_ITERATE_PHDR)
134   # Restore the original state
135   cmake_pop_check_state()
136 #]=======================================================================]
138 macro(CMAKE_RESET_CHECK_STATE)
140   set(CMAKE_EXTRA_INCLUDE_FILES)
141   set(CMAKE_REQUIRED_INCLUDES)
142   set(CMAKE_REQUIRED_DEFINITIONS)
143   set(CMAKE_REQUIRED_LINK_OPTIONS)
144   set(CMAKE_REQUIRED_LIBRARIES)
145   set(CMAKE_REQUIRED_LINK_DIRECTORIES)
146   set(CMAKE_REQUIRED_FLAGS)
147   set(CMAKE_REQUIRED_QUIET)
149 endmacro()
151 macro(CMAKE_PUSH_CHECK_STATE)
153   if(NOT DEFINED _CMAKE_PUSH_CHECK_STATE_COUNTER)
154     set(_CMAKE_PUSH_CHECK_STATE_COUNTER 0)
155   endif()
157   math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}+1")
159   set(_CMAKE_EXTRA_INCLUDE_FILES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}        ${CMAKE_EXTRA_INCLUDE_FILES})
160   set(_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}          ${CMAKE_REQUIRED_INCLUDES})
161   set(_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}       ${CMAKE_REQUIRED_DEFINITIONS})
162   set(_CMAKE_REQUIRED_LINK_OPTIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}      ${CMAKE_REQUIRED_LINK_OPTIONS})
163   set(_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}         ${CMAKE_REQUIRED_LIBRARIES})
164   set(_CMAKE_REQUIRED_LINK_DIRECTORIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}  ${CMAKE_REQUIRED_LINK_DIRECTORIES})
165   set(_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}             ${CMAKE_REQUIRED_FLAGS})
166   set(_CMAKE_REQUIRED_QUIET_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}             ${CMAKE_REQUIRED_QUIET})
168   if (${ARGC} GREATER 0 AND "${ARGV0}" STREQUAL "RESET")
169     cmake_reset_check_state()
170   endif()
172 endmacro()
174 macro(CMAKE_POP_CHECK_STATE)
176 # don't pop more than we pushed
177   if("${_CMAKE_PUSH_CHECK_STATE_COUNTER}" GREATER "0")
179     set(CMAKE_EXTRA_INCLUDE_FILES       ${_CMAKE_EXTRA_INCLUDE_FILES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
180     set(CMAKE_REQUIRED_INCLUDES         ${_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
181     set(CMAKE_REQUIRED_DEFINITIONS      ${_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
182     set(CMAKE_REQUIRED_LINK_OPTIONS     ${_CMAKE_REQUIRED_LINK_OPTIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
183     set(CMAKE_REQUIRED_LIBRARIES        ${_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
184     set(CMAKE_REQUIRED_LINK_DIRECTORIES ${_CMAKE_REQUIRED_LINK_DIRECTORIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
185     set(CMAKE_REQUIRED_FLAGS            ${_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
186     set(CMAKE_REQUIRED_QUIET            ${_CMAKE_REQUIRED_QUIET_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
188     math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}-1")
189   endif()
191 endmacro()