1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file LICENSE.rst or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
CheckPrototypeDefinition
------------------------
This module provides a command to check if a C function has the expected
prototype.
Load this module in a CMake project with:
.. code-block:: cmake
include(CheckPrototypeDefinition)
Commands
^^^^^^^^
This module provides the following command:
.. command:: check_prototype_definition
Checks if a C function has the expected prototype:
.. code-block:: cmake
check_prototype_definition(<function> <prototype> <return> <headers> <variable>)
``<function>``
The name of the function whose prototype is being checked.
``<prototype>``
The expected prototype of the function, provided as a string.
``<return>``
The return value of the function. This will be used as a return value in
the function definition body of the generated test program to verify that
the function's return type matches the expected type.
``<headers>``
A :ref:`semicolon-separated list <CMake Language Lists>` of header file
names required for checking the function prototype.
``<variable>``
The name of the variable to store the check result. This variable will be
created as an internal cache variable.
This command generates a test program and verifies that it builds without
errors. The generated test program includes specified ``<headers>``, defines
a function with given literal ``<prototype>`` and ``<return>`` value and
then uses the specified ``<function>``. The simplified test program can be
illustrated as:
.. code-block:: c
#include <headers>
// ...
<prototype> { return <return>; }
int main(...) { ...<function>()... }
.. 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
.. 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
Examples
^^^^^^^^
Checking if the ``getpwent_r()`` function on Solaris/illumos systems has the
expected prototype:
.. code-block:: cmake
include(CheckPrototypeDefinition)
check_prototype_definition(
getpwent_r
"struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)"
"NULL"
"unistd.h;pwd.h"
HAVE_SOLARIS_GETPWENT_R
)
#]=======================================================================]
#
get_filename_component(__check_proto_def_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
include_guard(GLOBAL)
function(check_prototype_definition _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIABLE)
if (NOT DEFINED ${_VARIABLE})
if(NOT CMAKE_REQUIRED_QUIET)
message(CHECK_START "Checking prototype ${_FUNCTION} for ${_VARIABLE}")
endif()
set(CHECK_PROTOTYPE_DEFINITION_CONTENT "/* */\n")
set(CHECK_PROTOTYPE_DEFINITION_FLAGS ${CMAKE_REQUIRED_FLAGS})
if (CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_PROTOTYPE_DEFINITION_LINK_OPTIONS
LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
else()
set(CHECK_PROTOTYPE_DEFINITION_LINK_OPTIONS)
endif()
if (CMAKE_REQUIRED_LIBRARIES)
set(CHECK_PROTOTYPE_DEFINITION_LIBS
LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
else()
set(CHECK_PROTOTYPE_DEFINITION_LIBS)
endif()
if (CMAKE_REQUIRED_INCLUDES)
set(CMAKE_SYMBOL_EXISTS_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
else()
set(CMAKE_SYMBOL_EXISTS_INCLUDES)
endif()
if(CMAKE_REQUIRED_LINK_DIRECTORIES)
set(_CPD_LINK_DIRECTORIES
"-DLINK_DIRECTORIES:STRING=${CMAKE_REQUIRED_LINK_DIRECTORIES}")
else()
set(_CPD_LINK_DIRECTORIES)
endif()
foreach(_FILE ${_HEADER})
string(APPEND CHECK_PROTOTYPE_DEFINITION_HEADER
"#include <${_FILE}>\n")
endforeach()
set(CHECK_PROTOTYPE_DEFINITION_SYMBOL ${_FUNCTION})
set(CHECK_PROTOTYPE_DEFINITION_PROTO ${_PROTOTYPE})
set(CHECK_PROTOTYPE_DEFINITION_RETURN ${_RETURN})
file(READ ${__check_proto_def_dir}/CheckPrototypeDefinition.c.in _SOURCE)
string(CONFIGURE "${_SOURCE}" _SOURCE @ONLY)
try_compile(${_VARIABLE}
SOURCE_FROM_VAR CheckPrototypeDefinition.c _SOURCE
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
${CHECK_PROTOTYPE_DEFINITION_LINK_OPTIONS}
${CHECK_PROTOTYPE_DEFINITION_LIBS}
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CHECK_PROTOTYPE_DEFINITION_FLAGS}
"${CMAKE_SYMBOL_EXISTS_INCLUDES}"
"${_CPD_LINK_DIRECTORIES}"
)
unset(_CPD_LINK_DIRECTORIES)
if (${_VARIABLE})
set(${_VARIABLE} 1 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
if(NOT CMAKE_REQUIRED_QUIET)
message(CHECK_PASS "True")
endif()
else ()
if(NOT CMAKE_REQUIRED_QUIET)
message(CHECK_FAIL "False")
endif()
set(${_VARIABLE} 0 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
endif ()
endif()
endfunction()
|