File: CheckPrototypeDefinition.cmake

package info (click to toggle)
cmake 4.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 147,284 kB
  • sloc: ansic: 403,915; cpp: 290,772; sh: 4,102; python: 3,357; yacc: 3,106; lex: 1,189; f90: 532; asm: 471; lisp: 375; cs: 270; java: 266; fortran: 230; perl: 217; objc: 215; xml: 198; makefile: 97; javascript: 83; pascal: 63; tcl: 55; php: 25; ruby: 22
file content (173 lines) | stat: -rw-r--r-- 5,436 bytes parent folder | download
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()