| # - 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(<FLAG> [<VARIANT>]) | |
| # | |
| # - 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() |