From 8f2b7d2f53439173bcaa37aca797e4a04bf9288f Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Fri, 17 Jan 2025 15:44:33 +0100 Subject: [PATCH] CMakePushCheckState: Enhance documentation This describes module macros as a list separately, adds some formatting with synced lowercase code style, and extends examples a bit. Additionally, the CMAKE_REQUIRED_QUIET variable is listed. --- Modules/CMakePushCheckState.cmake | 144 ++++++++++++++++++++++++------ Modules/FindGIF.cmake | 4 +- Modules/FindOpenCL.cmake | 4 +- 3 files changed, 123 insertions(+), 29 deletions(-) diff --git a/Modules/CMakePushCheckState.cmake b/Modules/CMakePushCheckState.cmake index 50bd90bc53..0cd55e124c 100644 --- a/Modules/CMakePushCheckState.cmake +++ b/Modules/CMakePushCheckState.cmake @@ -5,38 +5,132 @@ CMakePushCheckState ------------------- +This module provides macros for managing the state of variables that influence +how various CMake check commands (e.g., ``check_symbol_exists()``, etc.) are +performed. These macros save, reset, and restore the following variables: +* ``CMAKE_REQUIRED_FLAGS`` +* ``CMAKE_REQUIRED_DEFINITIONS`` +* ``CMAKE_REQUIRED_INCLUDES`` +* ``CMAKE_REQUIRED_LINK_OPTIONS`` +* ``CMAKE_REQUIRED_LIBRARIES`` +* ``CMAKE_REQUIRED_LINK_DIRECTORIES`` +* ``CMAKE_REQUIRED_QUIET`` +* ``CMAKE_EXTRA_INCLUDE_FILES`` -This module defines three macros: ``CMAKE_PUSH_CHECK_STATE()`` -``CMAKE_POP_CHECK_STATE()`` and ``CMAKE_RESET_CHECK_STATE()`` These macros can -be used to save, restore and reset (i.e., clear contents) the state of -the variables ``CMAKE_REQUIRED_FLAGS``, ``CMAKE_REQUIRED_DEFINITIONS``, -``CMAKE_REQUIRED_LINK_OPTIONS``, ``CMAKE_REQUIRED_LIBRARIES``, -``CMAKE_REQUIRED_LINK_DIRECTORIES``, -``CMAKE_REQUIRED_INCLUDES`` and ``CMAKE_EXTRA_INCLUDE_FILES`` used by the -various Check-files coming with CMake, like e.g. ``check_function_exists()`` -etc. -The variable contents are pushed on a stack, pushing multiple times is -supported. This is useful e.g. when executing such tests in a Find-module, -where they have to be set, but after the Find-module has been executed they -should have the same value as they had before. +Macros +^^^^^^ -``CMAKE_PUSH_CHECK_STATE()`` macro receives optional argument ``RESET``. -Whether it's specified, ``CMAKE_PUSH_CHECK_STATE()`` will set all -``CMAKE_REQUIRED_*`` variables to empty values, same as -``CMAKE_RESET_CHECK_STATE()`` call will do. +.. command:: cmake_push_check_state -Usage: + Saves (pushes) the current states of the above variables onto a stack. This + is typically used to preserve the current configuration before making + temporary modifications for specific checks. + + .. code-block:: cmake + + cmake_push_check_state([RESET]) + + ``RESET`` + When this option is specified, the macro 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() + + This macro can be used, for example, 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() + + This macro is used 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()``. + +These macros are useful for scoped configuration, for example, in +:ref:`Find 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. + +.. note:: + + Other CMake variables, such as ``CMAKE__FLAGS``, propagate to all checks + regardless of these macros, as those fundamental variables are designed to + influence the global state of the build system. + +Examples +^^^^^^^^ .. code-block:: cmake - cmake_push_check_state(RESET) - set(CMAKE_REQUIRED_DEFINITIONS -DSOME_MORE_DEF) - check_function_exists(...) - cmake_reset_check_state() - set(CMAKE_REQUIRED_DEFINITIONS -DANOTHER_DEF) - check_function_exists(...) - cmake_pop_check_state() + 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() + +Variable states can be pushed onto the stack multiple times, allowing for nested +or sequential configurations. 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) diff --git a/Modules/FindGIF.cmake b/Modules/FindGIF.cmake index 9a11b88e56..11fa3c89c4 100644 --- a/Modules/FindGIF.cmake +++ b/Modules/FindGIF.cmake @@ -79,7 +79,7 @@ find_library(GIF_LIBRARY if(GIF_INCLUDE_DIR) include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake) include(${CMAKE_CURRENT_LIST_DIR}/CheckStructHasMember.cmake) - CMAKE_PUSH_CHECK_STATE() + cmake_push_check_state() set(CMAKE_REQUIRED_QUIET ${GIF_FIND_QUIETLY}) set(CMAKE_REQUIRED_INCLUDES "${GIF_INCLUDE_DIR}") @@ -105,7 +105,7 @@ if(GIF_INCLUDE_DIR) unset(_GIF_MIN) unset(_GIF_REL) unset(_GIF_DEFS) - CMAKE_POP_CHECK_STATE() + cmake_pop_check_state() endif() include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) diff --git a/Modules/FindOpenCL.cmake b/Modules/FindOpenCL.cmake index b3fa1cce0f..c0f45df59d 100644 --- a/Modules/FindOpenCL.cmake +++ b/Modules/FindOpenCL.cmake @@ -46,7 +46,7 @@ function(_FIND_OPENCL_VERSION) include(CMakePushCheckState) set(CMAKE_REQUIRED_QUIET ${OpenCL_FIND_QUIETLY}) - CMAKE_PUSH_CHECK_STATE() + cmake_push_check_state() foreach(VERSION "3_0" "2_2" "2_1" "2_0" "1_2" "1_1" "1_0") set(CMAKE_REQUIRED_INCLUDES "${OpenCL_INCLUDE_DIR}") @@ -73,7 +73,7 @@ function(_FIND_OPENCL_VERSION) break() endif() endforeach() - CMAKE_POP_CHECK_STATE() + cmake_pop_check_state() endfunction() find_path(OpenCL_INCLUDE_DIR