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
|
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file LICENSE.rst or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
CheckStructHasMember
--------------------
This module provides a command to check whether a struct or class has a
specified member variable.
Load this module in a CMake project with:
.. code-block:: cmake
include(CheckStructHasMember)
Commands
^^^^^^^^
This module provides the following command:
.. command:: check_struct_has_member
Checks once if the given struct or class has the specified member variable:
.. code-block:: cmake
check_struct_has_member(
<struct>
<member>
<headers>
<variable>
[LANGUAGE <language>]
)
This command checks once whether the struct or class ``<struct>`` contains
the specified ``<member>`` after including the given header(s) ``<headers>``
where the prototype should be declared. Multiple header files can be
specified in one argument as a string using a :ref:`semicolon-separated list
<CMake Language Lists>`. The result is stored in an internal cache variable
``<variable>``.
The options are:
``LANGUAGE <language>``
Use the ``<language>`` compiler to perform the check.
Acceptable values are ``C`` and ``CXX``.
If not specified, it defaults to ``C``.
.. 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
^^^^^^^^
Example: Checking C Struct Member
"""""""""""""""""""""""""""""""""
In the following example, this module checks if the C struct ``timeval`` has
a member variable ``tv_sec`` after including the ``<sys/select.h>`` header.
The result of the check is stored in the internal cache variable
``HAVE_TIMEVAL_TV_SEC``.
.. code-block:: cmake
include(CheckStructHasMember)
check_struct_has_member(
"struct timeval"
tv_sec
sys/select.h
HAVE_TIMEVAL_TV_SEC
)
Example: Checking C++ Struct Member
"""""""""""""""""""""""""""""""""""
In the following example, this module checks if the C++ struct ``std::tm``
has a member variable ``tm_gmtoff`` after including the ``<ctime>`` header.
The result of the check is stored in the internal cache variable
``HAVE_TM_GMTOFF``.
.. code-block:: cmake
include(CheckStructHasMember)
check_struct_has_member(
std::tm
tm_gmtoff
ctime
HAVE_TM_GMTOFF
LANGUAGE CXX
)
Example: Isolated Check With Compile Definitions
""""""""""""""""""""""""""""""""""""""""""""""""
In the following example, the check is performed with temporarily modified
compile definitions using the :module:`CMakePushCheckState` module:
.. code-block:: cmake
include(CheckStructHasMember)
include(CMakePushCheckState)
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
check_struct_has_member(
"struct utsname"
domainname
sys/utsname.h
HAVE_UTSNAME_DOMAINNAME
)
cmake_pop_check_state()
#]=======================================================================]
include_guard(GLOBAL)
include(CheckSourceCompiles)
macro (CHECK_STRUCT_HAS_MEMBER _STRUCT _MEMBER _HEADER _RESULT)
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 "
${_INCLUDE_FILES}
int main(void)
{
(void)sizeof(((${_STRUCT} *)0)->${_MEMBER});
return 0;
}
")
if("${_lang}" STREQUAL "C")
check_source_compiles(C "${_CHECK_STRUCT_MEMBER_SOURCE_CODE}" ${_RESULT})
elseif("${_lang}" STREQUAL "CXX")
check_source_compiles(CXX "${_CHECK_STRUCT_MEMBER_SOURCE_CODE}" ${_RESULT})
else()
message(FATAL_ERROR "Unknown language:\n ${_lang}\nSupported languages: C, CXX.\n")
endif()
endmacro ()
# FIXME(#24994): The following modules are included only for compatibility
# with projects that accidentally relied on them with CMake 3.26 and below.
include(CheckCSourceCompiles)
include(CheckCXXSourceCompiles)
|