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:
5CheckIncludeFileCXX
6-------------------
7
8Provides a macro to check if a header file can be included in ``CXX``.
9
10.. command:: CHECK_INCLUDE_FILE_CXX
11
12  .. code-block:: cmake
13
14    CHECK_INCLUDE_FILE_CXX(<include> <variable> [<flags>])
15
16  Check if the given ``<include>`` file may be included in a ``CXX``
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 modules :module:`CheckIncludeFile` and :module:`CheckIncludeFiles`
42to check for one or more ``C`` headers.
43#]=======================================================================]
44
45include_guard(GLOBAL)
46
47macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE)
48  if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}")
49    if(CMAKE_REQUIRED_INCLUDES)
50      set(CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS "-DINCLUDE_DIRECTORIES=${CMAKE_REQUIRED_INCLUDES}")
51    else()
52      set(CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS)
53    endif()
54    set(MACRO_CHECK_INCLUDE_FILE_FLAGS ${CMAKE_REQUIRED_FLAGS})
55    set(CHECK_INCLUDE_FILE_VAR ${INCLUDE})
56    configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in
57      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx)
58    if(NOT CMAKE_REQUIRED_QUIET)
59      message(CHECK_START "Looking for C++ include ${INCLUDE}")
60    endif()
61    if(${ARGC} EQUAL 3)
62      set(CMAKE_CXX_FLAGS_SAVE ${CMAKE_CXX_FLAGS})
63      string(APPEND CMAKE_CXX_FLAGS " ${ARGV2}")
64    endif()
65
66    set(_CIF_LINK_OPTIONS)
67    if(CMAKE_REQUIRED_LINK_OPTIONS)
68      set(_CIF_LINK_OPTIONS LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
69    endif()
70
71    set(_CIF_LINK_LIBRARIES "")
72    if(CMAKE_REQUIRED_LIBRARIES)
73      cmake_policy(GET CMP0075 _CIF_CMP0075
74        PARENT_SCOPE # undocumented, do not use outside of CMake
75        )
76      if("x${_CIF_CMP0075}x" STREQUAL "xNEWx")
77        set(_CIF_LINK_LIBRARIES LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
78      elseif("x${_CIF_CMP0075}x" STREQUAL "xOLDx")
79      elseif(NOT _CIF_CMP0075_WARNED)
80        set(_CIF_CMP0075_WARNED 1)
81        message(AUTHOR_WARNING
82          "Policy CMP0075 is not set: Include file check macros honor CMAKE_REQUIRED_LIBRARIES.  "
83          "Run \"cmake --help-policy CMP0075\" for policy details.  "
84          "Use the cmake_policy command to set the policy and suppress this warning."
85          "\n"
86          "CMAKE_REQUIRED_LIBRARIES is set to:\n"
87          "  ${CMAKE_REQUIRED_LIBRARIES}\n"
88          "For compatibility with CMake 3.11 and below this check is ignoring it."
89          )
90      endif()
91      unset(_CIF_CMP0075)
92    endif()
93
94    try_compile(${VARIABLE}
95      ${CMAKE_BINARY_DIR}
96      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx
97      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
98      ${_CIF_LINK_OPTIONS}
99      ${_CIF_LINK_LIBRARIES}
100      CMAKE_FLAGS
101      -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS}
102      "${CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS}"
103      OUTPUT_VARIABLE OUTPUT)
104    unset(_CIF_LINK_OPTIONS)
105    unset(_CIF_LINK_LIBRARIES)
106
107    if(${ARGC} EQUAL 3)
108      set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_SAVE})
109    endif()
110
111    if(${VARIABLE})
112      if(NOT CMAKE_REQUIRED_QUIET)
113        message(CHECK_PASS "found")
114      endif()
115      set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}")
116      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
117        "Determining if the include file ${INCLUDE} "
118        "exists passed with the following output:\n"
119        "${OUTPUT}\n\n")
120    else()
121      if(NOT CMAKE_REQUIRED_QUIET)
122        message(CHECK_FAIL "not found")
123      endif()
124      set(${VARIABLE} "" CACHE INTERNAL "Have include ${INCLUDE}")
125      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
126        "Determining if the include file ${INCLUDE} "
127        "exists failed with the following output:\n"
128        "${OUTPUT}\n\n")
129    endif()
130  endif()
131endmacro()
132