1 # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
4 #[=======================================================================[.rst:
8 Provides a macro to check if a symbol exists as a function, variable,
11 .. command:: check_symbol_exists
15 check_symbol_exists(<symbol> <files> <variable>)
17 Check that the ``<symbol>`` is available after including given header
18 ``<files>`` and store the result in a ``<variable>``. Specify the list
19 of files in one argument as a semicolon-separated list.
20 ``<variable>`` will be created as an internal cache variable.
22 If the header files define the symbol as a macro it is considered
23 available and assumed to work. If the header files declare the symbol
24 as a function or variable then the symbol must also be available for
25 linking (so intrinsics may not be detected).
26 If the symbol is a type, enum value, or intrinsic it will not be recognized
27 (consider using :module:`CheckTypeSize` or :module:`CheckSourceCompiles`).
28 If the check needs to be done in C++, consider using
29 :module:`CheckCXXSymbolExists` instead.
31 The following variables may be set before calling this macro to modify
32 the way the check is run:
34 .. include:: /module/CMAKE_REQUIRED_FLAGS.txt
36 .. include:: /module/CMAKE_REQUIRED_DEFINITIONS.txt
38 .. include:: /module/CMAKE_REQUIRED_INCLUDES.txt
40 .. include:: /module/CMAKE_REQUIRED_LINK_OPTIONS.txt
42 .. include:: /module/CMAKE_REQUIRED_LIBRARIES.txt
44 .. include:: /module/CMAKE_REQUIRED_LINK_DIRECTORIES.txt
46 .. include:: /module/CMAKE_REQUIRED_QUIET.txt
52 include(CheckSymbolExists)
54 # Check for macro SEEK_SET
55 check_symbol_exists(SEEK_SET "stdio.h" HAVE_SEEK_SET)
56 # Check for function fopen
57 check_symbol_exists(fopen "stdio.h" HAVE_FOPEN)
58 #]=======================================================================]
62 macro(CHECK_SYMBOL_EXISTS SYMBOL FILES VARIABLE)
63 if(CMAKE_C_COMPILER_LOADED)
64 __CHECK_SYMBOL_EXISTS_FILTER_FLAGS(C)
65 __CHECK_SYMBOL_EXISTS_IMPL(CheckSymbolExists.c "${SYMBOL}" "${FILES}" "${VARIABLE}" )
66 __CHECK_SYMBOL_EXISTS_RESTORE_FLAGS(C)
67 elseif(CMAKE_CXX_COMPILER_LOADED)
68 __CHECK_SYMBOL_EXISTS_FILTER_FLAGS(CXX)
69 __CHECK_SYMBOL_EXISTS_IMPL(CheckSymbolExists.cxx "${SYMBOL}" "${FILES}" "${VARIABLE}" )
70 __CHECK_SYMBOL_EXISTS_RESTORE_FLAGS(CXX)
72 message(FATAL_ERROR "CHECK_SYMBOL_EXISTS needs either C or CXX language enabled")
76 macro(__CHECK_SYMBOL_EXISTS_FILTER_FLAGS LANG)
77 if(CMAKE_TRY_COMPILE_CONFIGURATION)
78 string(TOUPPER "${CMAKE_TRY_COMPILE_CONFIGURATION}" _tc_config)
80 set(_tc_config "DEBUG")
82 foreach(v CMAKE_${LANG}_FLAGS CMAKE_${LANG}_FLAGS_${_tc_config})
83 set(__${v}_SAVED "${${v}}")
84 string(REGEX REPLACE "(^| )-Werror([= ][^-][^ ]*)?( |$)" " " ${v} "${${v}}")
85 string(REGEX REPLACE "(^| )-pedantic-errors( |$)" " " ${v} "${${v}}")
89 macro(__CHECK_SYMBOL_EXISTS_RESTORE_FLAGS LANG)
90 if(CMAKE_TRY_COMPILE_CONFIGURATION)
91 string(TOUPPER "${CMAKE_TRY_COMPILE_CONFIGURATION}" _tc_config)
93 set(_tc_config "DEBUG")
95 foreach(v CMAKE_${LANG}_FLAGS CMAKE_${LANG}_FLAGS_${_tc_config})
96 set(${v} "${__${v}_SAVED}")
101 macro(__CHECK_SYMBOL_EXISTS_IMPL SOURCEFILE SYMBOL FILES VARIABLE)
102 if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}")
103 set(_CSE_SOURCE "/* */\n")
104 set(MACRO_CHECK_SYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS})
105 if(CMAKE_REQUIRED_LINK_OPTIONS)
106 set(CHECK_SYMBOL_EXISTS_LINK_OPTIONS
107 LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
109 set(CHECK_SYMBOL_EXISTS_LINK_OPTIONS)
111 if(CMAKE_REQUIRED_LIBRARIES)
112 set(CHECK_SYMBOL_EXISTS_LIBS
113 LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
115 set(CHECK_SYMBOL_EXISTS_LIBS)
117 if(CMAKE_REQUIRED_INCLUDES)
118 set(CMAKE_SYMBOL_EXISTS_INCLUDES
119 "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
121 set(CMAKE_SYMBOL_EXISTS_INCLUDES)
124 if(CMAKE_REQUIRED_LINK_DIRECTORIES)
125 set(_CSE_LINK_DIRECTORIES
126 "-DLINK_DIRECTORIES:STRING=${CMAKE_REQUIRED_LINK_DIRECTORIES}")
128 set(_CSE_LINK_DIRECTORIES)
130 foreach(FILE ${FILES})
131 string(APPEND _CSE_SOURCE
132 "#include <${FILE}>\n")
134 string(APPEND _CSE_SOURCE "
135 int main(int argc, char** argv)
138 set(_CSE_CHECK_NON_MACRO "return ((int*)(&${SYMBOL}))[argc];")
139 if("${SYMBOL}" MATCHES "^[a-zA-Z_][a-zA-Z0-9_]*$")
140 # The SYMBOL has a legal macro name. Test whether it exists as a macro.
141 string(APPEND _CSE_SOURCE "
143 ${_CSE_CHECK_NON_MACRO}
149 # The SYMBOL cannot be a macro (e.g., a template function).
150 string(APPEND _CSE_SOURCE "
151 ${_CSE_CHECK_NON_MACRO}")
153 string(APPEND _CSE_SOURCE "
155 unset(_CSE_CHECK_NON_MACRO)
157 if(NOT CMAKE_REQUIRED_QUIET)
158 message(CHECK_START "Looking for ${SYMBOL}")
160 try_compile(${VARIABLE}
161 SOURCE_FROM_VAR "${SOURCEFILE}" _CSE_SOURCE
162 COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
163 ${CHECK_SYMBOL_EXISTS_LINK_OPTIONS}
164 ${CHECK_SYMBOL_EXISTS_LIBS}
166 -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_SYMBOL_EXISTS_FLAGS}
167 "${CMAKE_SYMBOL_EXISTS_INCLUDES}"
168 "${_CSE_LINK_DIRECTORIES}"
170 unset(_CSE_LINK_DIRECTORIES)
172 if(NOT CMAKE_REQUIRED_QUIET)
173 message(CHECK_PASS "found")
175 set(${VARIABLE} 1 CACHE INTERNAL "Have symbol ${SYMBOL}")
177 if(NOT CMAKE_REQUIRED_QUIET)
178 message(CHECK_FAIL "not found")
180 set(${VARIABLE} "" CACHE INTERNAL "Have symbol ${SYMBOL}")