1# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2# file Copyright.txt or https://cmake.org/licensing for details.
3
4#[=======================================================================[.rst:
5CheckIncludeFile
6----------------
7
8Provides a macro to check if a header file can be included in ``C``.
9
10.. command:: CHECK_INCLUDE_FILE
11
12  .. code-block:: cmake
13
14    CHECK_INCLUDE_FILE(<include> <variable> [<flags>])
15
16  Check if the given ``<include>`` file may be included in a ``C``
17  source file and store the result in an internal cache entry named
18  ``<variable>``.  The optional third argument may be used to add
19  compilation flags to the check (or use ``CMAKE_REQUIRED_FLAGS`` below).
20
21The following variables may be set before calling this macro to modify
22the way the check is run:
23
24``CMAKE_REQUIRED_FLAGS``
25  string of compile command line flags.
26``CMAKE_REQUIRED_DEFINITIONS``
27  a :ref:`;-list <CMake Language Lists>` of macros to define (-DFOO=bar).
28``CMAKE_REQUIRED_INCLUDES``
29  a :ref:`;-list <CMake Language Lists>` of header search paths to pass to
30  the compiler.
31``CMAKE_REQUIRED_LINK_OPTIONS``
32  .. versionadded:: 3.14
33    a :ref:`;-list <CMake Language Lists>` of options to add to the link command.
34``CMAKE_REQUIRED_LIBRARIES``
35  a :ref:`;-list <CMake Language Lists>` of libraries to add to the link
36  command. See policy :policy:`CMP0075`.
37``CMAKE_REQUIRED_QUIET``
38  .. versionadded:: 3.1
39    execute quietly without messages.
40
41See the :module:`CheckIncludeFiles` module to check for multiple headers
42at once.  See the :module:`CheckIncludeFileCXX` module to check for headers
43using the ``CXX`` language.
44#]=======================================================================]
45
46include_guard(GLOBAL)
47
48macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE)
49  if(NOT DEFINED "${VARIABLE}")
50    if(CMAKE_REQUIRED_INCLUDES)
51      set(CHECK_INCLUDE_FILE_C_INCLUDE_DIRS "-DINCLUDE_DIRECTORIES=${CMAKE_REQUIRED_INCLUDES}")
52    else()
53      set(CHECK_INCLUDE_FILE_C_INCLUDE_DIRS)
54    endif()
55    set(MACRO_CHECK_INCLUDE_FILE_FLAGS ${CMAKE_REQUIRED_FLAGS})
56    set(CHECK_INCLUDE_FILE_VAR ${INCLUDE})
57    configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.c.in
58      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c)
59    if(NOT CMAKE_REQUIRED_QUIET)
60      message(CHECK_START "Looking for ${INCLUDE}")
61    endif()
62    if(${ARGC} EQUAL 3)
63      set(CMAKE_C_FLAGS_SAVE ${CMAKE_C_FLAGS})
64      string(APPEND CMAKE_C_FLAGS " ${ARGV2}")
65    endif()
66
67    set(_CIF_LINK_OPTIONS)
68    if(CMAKE_REQUIRED_LINK_OPTIONS)
69      set(_CIF_LINK_OPTIONS LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
70    endif()
71
72    set(_CIF_LINK_LIBRARIES "")
73    if(CMAKE_REQUIRED_LIBRARIES)
74      cmake_policy(GET CMP0075 _CIF_CMP0075
75        PARENT_SCOPE # undocumented, do not use outside of CMake
76        )
77      if("x${_CIF_CMP0075}x" STREQUAL "xNEWx")
78        set(_CIF_LINK_LIBRARIES LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
79      elseif("x${_CIF_CMP0075}x" STREQUAL "xOLDx")
80      elseif(NOT _CIF_CMP0075_WARNED)
81        set(_CIF_CMP0075_WARNED 1)
82        message(AUTHOR_WARNING
83          "Policy CMP0075 is not set: Include file check macros honor CMAKE_REQUIRED_LIBRARIES.  "
84          "Run \"cmake --help-policy CMP0075\" for policy details.  "
85          "Use the cmake_policy command to set the policy and suppress this warning."
86          "\n"
87          "CMAKE_REQUIRED_LIBRARIES is set to:\n"
88          "  ${CMAKE_REQUIRED_LIBRARIES}\n"
89          "For compatibility with CMake 3.11 and below this check is ignoring it."
90          )
91      endif()
92      unset(_CIF_CMP0075)
93    endif()
94
95    try_compile(${VARIABLE}
96      ${CMAKE_BINARY_DIR}
97      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c
98      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
99      ${_CIF_LINK_OPTIONS}
100      ${_CIF_LINK_LIBRARIES}
101      CMAKE_FLAGS
102      -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS}
103      "${CHECK_INCLUDE_FILE_C_INCLUDE_DIRS}"
104      OUTPUT_VARIABLE OUTPUT)
105    unset(_CIF_LINK_OPTIONS)
106    unset(_CIF_LINK_LIBRARIES)
107
108    if(${ARGC} EQUAL 3)
109      set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS_SAVE})
110    endif()
111
112    if(${VARIABLE})
113      if(NOT CMAKE_REQUIRED_QUIET)
114        message(CHECK_PASS "found")
115      endif()
116      set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}")
117      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
118        "Determining if the include file ${INCLUDE} "
119        "exists passed with the following output:\n"
120        "${OUTPUT}\n\n")
121    else()
122      if(NOT CMAKE_REQUIRED_QUIET)
123        message(CHECK_FAIL "not found")
124      endif()
125      set(${VARIABLE} "" CACHE INTERNAL "Have include ${INCLUDE}")
126      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
127        "Determining if the include file ${INCLUDE} "
128        "exists failed with the following output:\n"
129        "${OUTPUT}\n\n")
130    endif()
131  endif()
132endmacro()
133