CheckStructHasMember.cmake 2.43 KB
Newer Older
1 2 3
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

4 5 6 7 8 9
#[=======================================================================[.rst:
CheckStructHasMember
--------------------

Check if the given struct or class has the specified member variable

10
.. command:: CHECK_STRUCT_HAS_MEMBER
11

12
  .. code-block:: cmake
13

14 15
    CHECK_STRUCT_HAS_MEMBER(<struct> <member> <header> <variable>
                            [LANGUAGE <language>])
16

17 18 19 20 21 22 23
  ::

    <struct> - the name of the struct or class you are interested in
    <member> - the member which existence you want to check
    <header> - the header(s) where the prototype should be declared
    <variable> - variable to store the result
    <language> - the compiler to use (C or CXX)
24 25 26 27 28 29 30 31 32 33 34



The following variables may be set before calling this macro to modify
the way the check is run:

::

  CMAKE_REQUIRED_FLAGS = string of compile command line flags
  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
  CMAKE_REQUIRED_INCLUDES = list of include directories
35
  CMAKE_REQUIRED_LINK_OPTIONS = list of options to pass to link command
36 37 38 39
  CMAKE_REQUIRED_LIBRARIES = list of libraries to link
  CMAKE_REQUIRED_QUIET = execute quietly without messages


40 41 42
Example:

.. code-block:: cmake
43

44 45
  CHECK_STRUCT_HAS_MEMBER("struct timeval" tv_sec sys/select.h
                          HAVE_TIMEVAL_TV_SEC LANGUAGE C)
46
#]=======================================================================]
47

48
include_guard(GLOBAL)
49
include(CheckCSourceCompiles)
50
include(CheckCXXSourceCompiles)
51

52
macro (CHECK_STRUCT_HAS_MEMBER _STRUCT _MEMBER _HEADER _RESULT)
53 54 55 56 57 58 59 60 61 62 63 64 65 66
  set(_INCLUDE_FILES)
  foreach (it ${_HEADER})
    string(APPEND _INCLUDE_FILES "#include <${it}>\n")
  endforeach ()

  if("x${ARGN}" STREQUAL "x")
    set(_lang C)
  elseif("x${ARGN}" MATCHES "^xLANGUAGE;([a-zA-Z]+)$")
    set(_lang "${CMAKE_MATCH_1}")
  else()
    message(FATAL_ERROR "Unknown arguments:\n  ${ARGN}\n")
  endif()

  set(_CHECK_STRUCT_MEMBER_SOURCE_CODE "
67 68 69
${_INCLUDE_FILES}
int main()
{
70 71
  (void)sizeof(((${_STRUCT} *)0)->${_MEMBER});
  return 0;
72 73 74
}
")

75 76 77 78 79 80 81
  if("${_lang}" STREQUAL "C")
    CHECK_C_SOURCE_COMPILES("${_CHECK_STRUCT_MEMBER_SOURCE_CODE}" ${_RESULT})
  elseif("${_lang}" STREQUAL "CXX")
    CHECK_CXX_SOURCE_COMPILES("${_CHECK_STRUCT_MEMBER_SOURCE_CODE}" ${_RESULT})
  else()
    message(FATAL_ERROR "Unknown language:\n  ${_lang}\nSupported languages: C, CXX.\n")
  endif()
82
endmacro ()