CheckSymbolExists.cmake 4.8 KB
Newer Older
1 2 3 4 5 6
#.rst:
# CheckSymbolExists
# -----------------
#
# Check if a symbol exists as a function, variable, or macro
#
7
# CHECK_SYMBOL_EXISTS(<symbol> <files> <variable>)
8
#
9
# Check that the <symbol> is available after including given header
10 11
# <files> and store the result in a <variable>.  Specify the list of
# files in one argument as a semicolon-separated list.
12
# <variable> will be created as an internal cache variable.
13 14
#
# If the header files define the symbol as a macro it is considered
15 16 17 18 19 20 21 22 23 24
# available and assumed to work.  If the header files declare the symbol
# as a function or variable then the symbol must also be available for
# linking.  If the symbol is a type or enum value it will not be
# recognized (consider using CheckTypeSize or CheckCSourceCompiles).  If
# the check needs to be done in C++, consider using
# CHECK_CXX_SYMBOL_EXISTS(), which does the same as
# CHECK_SYMBOL_EXISTS(), but in C++.
#
# The following variables may be set before calling this macro to modify
# the way the check is run:
25
#
26
# ::
27
#
28 29 30 31
#   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
#   CMAKE_REQUIRED_LIBRARIES = list of libraries to link
32
#   CMAKE_REQUIRED_QUIET = execute quietly without messages
33

34
#=============================================================================
35
# Copyright 2003-2011 Kitware, Inc.
36 37 38 39 40 41 42 43
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
44
# (To distribute this file outside of CMake, substitute the full
45 46
#  License text for the above reference.)

47
macro(CHECK_SYMBOL_EXISTS SYMBOL FILES VARIABLE)
48 49 50 51 52 53 54
  if(CMAKE_C_COMPILER_LOADED)
    _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
  elseif(CMAKE_CXX_COMPILER_LOADED)
    _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.cxx" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
  else()
    message(FATAL_ERROR "CHECK_SYMBOL_EXISTS needs either C or CXX language enabled")
  endif()
55
endmacro()
56

57
macro(_CHECK_SYMBOL_EXISTS SOURCEFILE SYMBOL FILES VARIABLE)
58
  if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}")
59 60 61 62
    set(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n")
    set(MACRO_CHECK_SYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS})
    if(CMAKE_REQUIRED_LIBRARIES)
      set(CHECK_SYMBOL_EXISTS_LIBS
63
        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
64
    else()
65
      set(CHECK_SYMBOL_EXISTS_LIBS)
66
    endif()
67 68
    if(CMAKE_REQUIRED_INCLUDES)
      set(CMAKE_SYMBOL_EXISTS_INCLUDES
69
        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
70
    else()
71
      set(CMAKE_SYMBOL_EXISTS_INCLUDES)
72
    endif()
73 74
    foreach(FILE ${FILES})
      set(CMAKE_CONFIGURABLE_FILE_CONTENT
75
        "${CMAKE_CONFIGURABLE_FILE_CONTENT}#include <${FILE}>\n")
76
    endforeach()
77
    set(CMAKE_CONFIGURABLE_FILE_CONTENT
78
      "${CMAKE_CONFIGURABLE_FILE_CONTENT}\nint main(int argc, char** argv)\n{\n  (void)argv;\n#ifndef ${SYMBOL}\n  return ((int*)(&${SYMBOL}))[argc];\n#else\n  (void)argc;\n  return 0;\n#endif\n}\n")
79

80
    configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
81
      "${SOURCEFILE}" @ONLY)
82

83 84 85
    if(NOT CMAKE_REQUIRED_QUIET)
      message(STATUS "Looking for ${SYMBOL}")
    endif()
86
    try_compile(${VARIABLE}
87
      ${CMAKE_BINARY_DIR}
88
      "${SOURCEFILE}"
89
      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
90
      ${CHECK_SYMBOL_EXISTS_LIBS}
91
      CMAKE_FLAGS
92
      -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_SYMBOL_EXISTS_FLAGS}
93
      "${CMAKE_SYMBOL_EXISTS_INCLUDES}"
94
      OUTPUT_VARIABLE OUTPUT)
95
    if(${VARIABLE})
96 97 98
      if(NOT CMAKE_REQUIRED_QUIET)
        message(STATUS "Looking for ${SYMBOL} - found")
      endif()
99 100
      set(${VARIABLE} 1 CACHE INTERNAL "Have symbol ${SYMBOL}")
      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
101 102
        "Determining if the ${SYMBOL} "
        "exist passed with the following output:\n"
103
        "${OUTPUT}\nFile ${SOURCEFILE}:\n"
104
        "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n")
105
    else()
106 107 108
      if(NOT CMAKE_REQUIRED_QUIET)
        message(STATUS "Looking for ${SYMBOL} - not found")
      endif()
109 110
      set(${VARIABLE} "" CACHE INTERNAL "Have symbol ${SYMBOL}")
      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
111 112
        "Determining if the ${SYMBOL} "
        "exist failed with the following output:\n"
113
        "${OUTPUT}\nFile ${SOURCEFILE}:\n"
114
        "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n")
115 116 117
    endif()
  endif()
endmacro()