| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- # file LICENSE.rst or https://cmake.org/licensing for details.
- include_guard(GLOBAL)
- #[=======================================================================[.rst:
- CMakePushCheckState
- -------------------
- This module provides commands for managing the state of variables that influence
- how various CMake check commands (e.g., :command:`check_symbol_exists`, etc.)
- are performed.
- Load this module in a CMake project with:
- .. code-block:: cmake
- include(CMakePushCheckState)
- This module provides the following commands, which are useful for scoped
- configuration, for example, in CMake modules or when performing checks in a
- controlled environment, ensuring that temporary modifications are isolated
- to the scope of the check and do not propagate into other parts of the build
- system:
- * :command:`cmake_push_check_state`
- * :command:`cmake_reset_check_state`
- * :command:`cmake_pop_check_state`
- Affected Variables
- ^^^^^^^^^^^^^^^^^^
- The following CMake variables are saved, reset, and restored by this module's
- commands:
- .. include:: /module/include/CMAKE_REQUIRED_FLAGS.rst
- .. include:: /module/include/CMAKE_REQUIRED_DEFINITIONS.rst
- .. include:: /module/include/CMAKE_REQUIRED_INCLUDES.rst
- .. include:: /module/include/CMAKE_REQUIRED_LINK_OPTIONS.rst
- .. include:: /module/include/CMAKE_REQUIRED_LIBRARIES.rst
- .. include:: /module/include/CMAKE_REQUIRED_LINK_DIRECTORIES.rst
- .. include:: /module/include/CMAKE_REQUIRED_QUIET.rst
- ``CMAKE_EXTRA_INCLUDE_FILES``
- .. versionadded:: 3.6
- Previously used already by the :command:`check_type_size` command; now
- also supported by this module.
- A :ref:`semicolon-separated list <CMake Language Lists>` of extra header
- files to include when performing the check.
- .. note::
- Other CMake variables, such as :variable:`CMAKE_<LANG>_FLAGS`, propagate
- to all checks regardless of commands provided by this module, as those
- fundamental variables are designed to influence the global state of the
- build system.
- Commands
- ^^^^^^^^
- .. command:: cmake_push_check_state
- Pushes (saves) the current states of the above variables onto a stack:
- .. code-block:: cmake
- cmake_push_check_state([RESET])
- Use this command to preserve the current configuration before making
- temporary modifications for specific checks.
- ``RESET``
- When this option is specified, the command not only saves the current states
- of the listed variables but also resets them to empty, allowing them to be
- reconfigured from a clean state.
- .. command:: cmake_reset_check_state
- Resets (clears) the contents of the variables listed above to empty states:
- .. code-block:: cmake
- cmake_reset_check_state()
- Use this command when performing multiple sequential checks that require
- entirely new configurations, ensuring no previous configuration
- unintentionally carries over.
- .. command:: cmake_pop_check_state
- Restores the states of the variables listed above to their values at the time
- of the most recent ``cmake_push_check_state()`` call:
- .. code-block:: cmake
- cmake_pop_check_state()
- Use this command to revert temporary changes made during a check. To
- prevent unexpected behavior, pair each ``cmake_push_check_state()`` with a
- corresponding ``cmake_pop_check_state()``.
- Examples
- ^^^^^^^^
- Example: Isolated Check With Compile Definitions
- """"""""""""""""""""""""""""""""""""""""""""""""
- In the following example, a check for the C symbol ``memfd_create()`` is
- performed with an additional ``_GNU_SOURCE`` compile definition, without
- affecting global compile flags. The ``RESET`` option is used to ensure
- that any prior values of the check-related variables are explicitly cleared
- before the check.
- .. code-block:: cmake
- include(CMakePushCheckState)
- # Save and reset the current state
- cmake_push_check_state(RESET)
- # Perform check with specific compile definitions
- set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
- include(CheckSymbolExists)
- check_symbol_exists(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE)
- # Restore the original state
- cmake_pop_check_state()
- Example: Nested Configuration Scopes
- """"""""""""""""""""""""""""""""""""
- In the following example, variable states are pushed onto the stack multiple
- times, allowing for sequential or nested checks. Each
- ``cmake_pop_check_state()`` restores the most recent pushed states.
- .. code-block:: cmake
- include(CMakePushCheckState)
- # Save and reset the current state
- cmake_push_check_state(RESET)
- # Perform the first check with additional libraries
- set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS})
- include(CheckSymbolExists)
- check_symbol_exists(dlopen "dlfcn.h" HAVE_DLOPEN)
- # Save current state
- cmake_push_check_state()
- # Perform the second check with libraries and additional compile definitions
- set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
- check_symbol_exists(dladdr "dlfcn.h" HAVE_DLADDR)
- message(STATUS "${CMAKE_REQUIRED_DEFINITIONS}")
- # Output: -D_GNU_SOURCE
- # Restore the previous state
- cmake_pop_check_state()
- message(STATUS "${CMAKE_REQUIRED_DEFINITIONS}")
- # Output here is empty
- # Reset variables to prepare for the next check
- cmake_reset_check_state()
- # Perform the next check only with additional compile definitions
- set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
- check_symbol_exists(dl_iterate_phdr "link.h" HAVE_DL_ITERATE_PHDR)
- # Restore the original state
- cmake_pop_check_state()
- #]=======================================================================]
- macro(CMAKE_RESET_CHECK_STATE)
- set(CMAKE_EXTRA_INCLUDE_FILES)
- set(CMAKE_REQUIRED_INCLUDES)
- set(CMAKE_REQUIRED_DEFINITIONS)
- set(CMAKE_REQUIRED_LINK_OPTIONS)
- set(CMAKE_REQUIRED_LIBRARIES)
- set(CMAKE_REQUIRED_LINK_DIRECTORIES)
- set(CMAKE_REQUIRED_FLAGS)
- set(CMAKE_REQUIRED_QUIET)
- endmacro()
- macro(CMAKE_PUSH_CHECK_STATE)
- if(NOT DEFINED _CMAKE_PUSH_CHECK_STATE_COUNTER)
- set(_CMAKE_PUSH_CHECK_STATE_COUNTER 0)
- endif()
- math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}+1")
- set(_CMAKE_EXTRA_INCLUDE_FILES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_EXTRA_INCLUDE_FILES})
- set(_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_INCLUDES})
- set(_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_DEFINITIONS})
- set(_CMAKE_REQUIRED_LINK_OPTIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_LINK_OPTIONS})
- set(_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_LIBRARIES})
- set(_CMAKE_REQUIRED_LINK_DIRECTORIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_LINK_DIRECTORIES})
- set(_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_FLAGS})
- set(_CMAKE_REQUIRED_QUIET_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_QUIET})
- if (${ARGC} GREATER 0 AND "${ARGV0}" STREQUAL "RESET")
- cmake_reset_check_state()
- endif()
- endmacro()
- macro(CMAKE_POP_CHECK_STATE)
- # don't pop more than we pushed
- if("${_CMAKE_PUSH_CHECK_STATE_COUNTER}" GREATER "0")
- set(CMAKE_EXTRA_INCLUDE_FILES ${_CMAKE_EXTRA_INCLUDE_FILES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
- set(CMAKE_REQUIRED_INCLUDES ${_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
- set(CMAKE_REQUIRED_DEFINITIONS ${_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
- set(CMAKE_REQUIRED_LINK_OPTIONS ${_CMAKE_REQUIRED_LINK_OPTIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
- set(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
- set(CMAKE_REQUIRED_LINK_DIRECTORIES ${_CMAKE_REQUIRED_LINK_DIRECTORIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
- set(CMAKE_REQUIRED_FLAGS ${_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
- set(CMAKE_REQUIRED_QUIET ${_CMAKE_REQUIRED_QUIET_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
- math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}-1")
- endif()
- endmacro()
|