diff --git a/Modules/CheckFortranFunctionExists.cmake b/Modules/CheckFortranFunctionExists.cmake index 09b33628ec..536a50d67e 100644 --- a/Modules/CheckFortranFunctionExists.cmake +++ b/Modules/CheckFortranFunctionExists.cmake @@ -5,35 +5,86 @@ CheckFortranFunctionExists -------------------------- -Check if a Fortran function exists. +This module provides a command to check whether a Fortran function exists. + +Load this module in a CMake project with: + +.. code-block:: cmake + + include(CheckFortranFunctionExists) + +Commands +^^^^^^^^ + +This module provides the following command: .. command:: check_fortran_function_exists + Checks once whether a Fortran function exists: + .. code-block:: cmake - check_fortran_function_exists( ) - - where + check_fortran_function_exists( ) ```` - the name of the Fortran function - ```` - variable to store the result; will be created as an internal cache variable. + The name of the Fortran function. -.. note:: + ```` + The name of the variable in which to store the check result. This + variable will be created as an internal cache variable. - This command does not detect functions in Fortran modules. In general it is - recommended to use :module:`CheckSourceCompiles` instead to determine if a - Fortran function or subroutine is available. + .. note:: -The following variables may be set before calling this macro to modify -the way the check is run: + This command does not detect functions provided by Fortran modules. In + general, it is recommended to use :module:`CheckSourceCompiles` instead + to determine whether a Fortran function or subroutine is available. + + .. rubric:: Variables Affecting the Check + + The following variables may be set before calling this command to modify + the way the check is run: .. include:: /module/include/CMAKE_REQUIRED_LINK_OPTIONS.rst .. include:: /module/include/CMAKE_REQUIRED_LIBRARIES.rst .. include:: /module/include/CMAKE_REQUIRED_LINK_DIRECTORIES.rst + +Examples +^^^^^^^^ + +Example: Isolated Check With Linked Libraries +""""""""""""""""""""""""""""""""""""""""""""" + +In the following example, this module is used in combination with the +:module:`CMakePushCheckState` module to temporarily modify the required +linked libraries (via ``CMAKE_REQUIRED_LIBRARIES``) and verify whether the +Fortran function ``dgesv`` is available for linking. The result is stored +in the internal cache variable ``PROJECT_HAVE_DGESV``: + +.. code-block:: cmake + + include(CheckFortranFunctionExists) + include(CMakePushCheckState) + + find_package(LAPACK) + + if(TARGET LAPACK::LAPACK) + cmake_push_check_state(RESET) + + set(CMAKE_REQUIRED_LIBRARIES LAPACK::LAPACK) + check_fortran_function_exists(dgesv PROJECT_HAVE_DGESV) + + cmake_pop_check_state() + endif() + +See Also +^^^^^^^^ + +* The :module:`CheckFunctionExists` module to check whether a C function + exists. +* The :module:`CheckSourceCompiles` module to check whether source code + can be compiled. #]=======================================================================] include_guard(GLOBAL) diff --git a/Modules/CheckFunctionExists.cmake b/Modules/CheckFunctionExists.cmake index 98b58b10d1..5d13f2b627 100644 --- a/Modules/CheckFunctionExists.cmake +++ b/Modules/CheckFunctionExists.cmake @@ -5,19 +5,49 @@ CheckFunctionExists ------------------- -Check once if a C function can be linked from system libraries. +This module provides a command to check whether a C function exists. + +Load this module in a CMake project with: + +.. code-block:: cmake + + include(CheckFunctionExists) + +Commands +^^^^^^^^ + +This module provides the following command: .. command:: check_function_exists + Checks once whether a C function can be linked from system libraries: + .. code-block:: cmake check_function_exists( ) - Checks that the ```` is provided by libraries on the system and store - the result in internal cache variable ````. + This command checks whether the ```` is provided by libraries + on the system, and stores the result in an internal cache variable + ````. -The following variables may be set before calling this macro to modify the -way the check is run: + .. note:: + + Prefer using :module:`CheckSymbolExists` or :module:`CheckSourceCompiles` + instead of this command, for the following reasons: + + * ``check_function_exists()`` can't detect functions that are inlined + in headers or defined as preprocessor macros. + + * ``check_function_exists()`` can't detect anything in the 32-bit + versions of the Win32 API, because of a mismatch in calling conventions. + + * ``check_function_exists()`` only verifies linking, it does not verify + that the function is declared in system headers. + + .. rubric:: Variables Affecting the Check + + The following variables may be set before calling this command to modify + the way the check is run: .. include:: /module/include/CMAKE_REQUIRED_FLAGS.rst @@ -33,19 +63,63 @@ way the check is run: .. include:: /module/include/CMAKE_REQUIRED_QUIET.rst -.. note:: +Examples +^^^^^^^^ - Prefer using :module:`CheckSymbolExists` or :module:`CheckSourceCompiles` - instead of this module, for the following reasons: +Example: Basic Usage +"""""""""""""""""""" - * ``check_function_exists()`` can't detect functions that are inlined - in headers or specified as a macro. +In the following example, a check is performed to determine whether the +linker sees the C function ``fopen()``, and the result is stored in the +``HAVE_FOPEN`` internal cache variable: - * ``check_function_exists()`` can't detect anything in the 32-bit - versions of the Win32 API, because of a mismatch in calling conventions. +.. code-block:: cmake - * ``check_function_exists()`` only verifies linking, it does not verify - that the function is declared in system headers. + include(CheckFunctionExists) + + check_function_exists(fopen HAVE_FOPEN) + +Example: Missing Declaration +"""""""""""""""""""""""""""" + +As noted above, the :module:`CheckSymbolExists` module is preferred for +checking C functions, since it also verifies whether the function is +declared or defined as a macro. In the following example, this module is +used to check an edge case where a function may not be declared in system +headers. For instance, on macOS, the ``fdatasync()`` function may be +available in the C library, but its declaration is not provided in the +``unistd.h`` system header. + +.. code-block:: cmake + :caption: ``CMakeLists.txt`` + + include(CheckFunctionExists) + include(CheckSymbolExists) + + check_symbol_exists(fdatasync "unistd.h" HAVE_FDATASYNC) + + # Check if fdatasync() is available in the C library. + if(NOT HAVE_FDATASYNC) + check_function_exists(fdatasync HAVE_FDATASYNC_WITHOUT_DECL) + endif() + +In such a case, the project can provide its own declaration if missing: + +.. code-block:: c + :caption: ``example.c`` + + #ifdef HAVE_FDATASYNC_WITHOUT_DECL + extern int fdatasync(int); + #endif + +See Also +^^^^^^^^ + +* The :module:`CheckSymbolExists` module to check whether a C symbol exists. +* The :module:`CheckSourceCompiles` module to check whether a source code + can be compiled. +* The :module:`CheckFortranFunctionExists` module to check whether a + Fortran function exists. #]=======================================================================] include_guard(GLOBAL)