# - Compile and run code to check for C++ features # # This functions compiles a source file under the `cmake` folder # and adds the corresponding `HAVE_[FILENAME]` flag to the CMake # environment # # cxx_feature_check( []) # # - Example # # include(CXXFeatureCheck) # cxx_feature_check(STD_REGEX) # Requires CMake 3.13+ if(__cxx_feature_check) return() endif() set(__cxx_feature_check INCLUDED) option(CXXFEATURECHECK_DEBUG OFF "Enable debug messages for CXX feature checks") function(cxx_feature_check_print log) if(CXXFEATURECHECK_DEBUG) message(STATUS "${log}") endif() endfunction() function(cxx_feature_check FEATURE) string(TOLOWER ${FEATURE} FILE) string(TOUPPER HAVE_${FEATURE} VAR) # Check if the variable is already defined to a true or false for a quick return. # This allows users to predefine the variable to skip the check. # Or, if the variable is already defined by a previous check, we skip the costly check. if (DEFINED ${VAR}) if (${VAR}) cxx_feature_check_print("Feature ${FEATURE} already enabled.") add_compile_definitions(${VAR}) else() cxx_feature_check_print("Feature ${FEATURE} already disabled.") endif() return() endif() set(FEATURE_CHECK_CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS}) if (ARGC GREATER 1) message(STATUS "Enabling additional flags: ${ARGV1}") list(APPEND FEATURE_CHECK_CMAKE_FLAGS ${ARGV1}) endif() if(CMAKE_CROSSCOMPILING) cxx_feature_check_print("Cross-compiling to test ${FEATURE}") try_compile( COMPILE_STATUS ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON CMAKE_FLAGS "${FEATURE_CHECK_CMAKE_FLAGS}" LINK_LIBRARIES "${BENCHMARK_CXX_LIBRARIES}" OUTPUT_VARIABLE COMPILE_OUTPUT_VAR ) if(COMPILE_STATUS) set(RUN_STATUS 0) message(WARNING "If you see build failures due to cross compilation, try setting ${VAR} to 0") endif() else() cxx_feature_check_print("Compiling and running to test ${FEATURE}") try_run( RUN_STATUS COMPILE_STATUS ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON CMAKE_FLAGS "${FEATURE_CHECK_CMAKE_FLAGS}" LINK_LIBRARIES "${BENCHMARK_CXX_LIBRARIES}" COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT RUN_OUTPUT_VARIABLE RUN_OUTPUT ) endif() if(COMPILE_STATUS AND RUN_STATUS EQUAL 0) message(STATUS "Performing Test ${FEATURE} -- success") set(${VAR} TRUE CACHE BOOL "" FORCE) add_compile_definitions(${VAR}) return() endif() set(${VAR} FALSE CACHE BOOL "" FORCE) message(STATUS "Performing Test ${FEATURE} -- failed") if(NOT COMPILE_STATUS) cxx_feature_check_print("Compile Output: ${COMPILE_OUTPUT}") else() cxx_feature_check_print("Run Output: ${RUN_OUTPUT}") endif() endfunction()