Last active
October 22, 2019 13:35
-
-
Save likema/dc4547af539f11d422653c2fa012c6bd to your computer and use it in GitHub Desktop.
CMake macro to check if given C source file compiles and links into an executable
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# - Check if given C source file compiles and links into an executable | |
# CHECK_C_COMPILES(<file> <var> [FAIL_REGEX <fail-regex>]) | |
# | |
# <file> - source file to try to compile, must define 'main' | |
# <var> - variable to store whether the source code compiled | |
# Will be created as an internal cache variable. | |
# <fail-regex> - fail if test output matches this regex | |
# | |
# The following variables may be set before calling this macro to modify | |
# the way the check is run: | |
# | |
# 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 | |
# CMAKE_REQUIRED_QUIET = execute quietly without messages | |
MACRO (CHECK_C_COMPILES SRC VAR) | |
IF (NOT DEFINED "${VAR}") | |
SET (_FAIL_REGEX) | |
SET (_key) | |
FOREACH (arg ${ARGN}) | |
IF ("${arg}" MATCHES "^(FAIL_REGEX)$") | |
SET (_key "${arg}") | |
ELSEIF (_key) | |
LIST (APPEND _${_key} "${arg}") | |
ELSE ("${arg}" MATCHES "^(FAIL_REGEX)$") | |
MESSAGE (FATAL_ERROR "Unknown argument:\n ${arg}\n") | |
ENDIF ("${arg}" MATCHES "^(FAIL_REGEX)$") | |
ENDFOREACH (arg ${ARGN}) | |
SET (MACRO_CHECK_FUNCTION_DEFINITIONS | |
"-D${VAR} ${CMAKE_REQUIRED_FLAGS}") | |
IF (CMAKE_REQUIRED_LIBRARIES) | |
SET (CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES | |
LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) | |
ELSE (CMAKE_REQUIRED_LIBRARIES) | |
SET (CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES) | |
ENDIF (CMAKE_REQUIRED_LIBRARIES) | |
IF (CMAKE_REQUIRED_INCLUDES) | |
SET (CHECK_C_SOURCE_COMPILES_ADD_INCLUDES | |
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") | |
ELSE (CMAKE_REQUIRED_INCLUDES) | |
SET (CHECK_C_SOURCE_COMPILES_ADD_INCLUDES) | |
ENDIF (CMAKE_REQUIRED_INCLUDES) | |
IF (NOT CMAKE_REQUIRED_QUIET) | |
MESSAGE (STATUS "Performing Test ${VAR}") | |
ENDIF (NOT CMAKE_REQUIRED_QUIET) | |
TRY_COMPILE (${VAR} | |
${CMAKE_BINARY_DIR} | |
${SRC} | |
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} | |
${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES} | |
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} | |
"${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}" | |
OUTPUT_VARIABLE OUTPUT) | |
FOREACH (_regex ${_FAIL_REGEX}) | |
IF ("${OUTPUT}" MATCHES "${_regex}") | |
SET (${VAR} 0) | |
ENDIF ("${OUTPUT}" MATCHES "${_regex}") | |
ENDFOREACH (_regex ${_FAIL_REGEX}) | |
IF (${VAR}) | |
SET (${VAR} 1 CACHE INTERNAL "Test ${VAR}") | |
IF (NOT CMAKE_REQUIRED_QUIET) | |
MESSAGE (STATUS "Performing Test ${VAR} - Success") | |
ENDIF (NOT CMAKE_REQUIRED_QUIET) | |
FILE (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log | |
"Performing C SOURCE FILE Test ${VAR} succeeded with the following output:\n" | |
"${OUTPUT}\n" | |
"Source file was:\n${SRC}\n") | |
ELSE (${VAR}) | |
IF (NOT CMAKE_REQUIRED_QUIET) | |
MESSAGE (STATUS "Performing Test ${VAR} - Failed") | |
ENDIF (NOT CMAKE_REQUIRED_QUIET) | |
SET (${VAR} "" CACHE INTERNAL "Test ${VAR}") | |
FILE (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log | |
"Performing C SOURCE FILE Test ${VAR} failed with the following output:\n" | |
"${OUTPUT}\n" | |
"Source file was:\n${SRC}\n") | |
ENDIF (${VAR}) | |
ENDIF (NOT DEFINED "${VAR}") | |
ENDMACRO (CHECK_C_COMPILES SRC VAR) | |
# vim: set ts=4 sw=4 sts=4 et: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Inspired by CHECK_C_SOURCE_COMPILES, which has the following drawbacks:
Only support source as string
When source string is to complicated, it may encounter syntax error: