1 2macro(_record_compiler_features lang compile_flags feature_list) 3 include("${CMAKE_ROOT}/Modules/Compiler/${CMAKE_${lang}_COMPILER_ID}-${lang}-FeatureTests.cmake" OPTIONAL) 4 5 string(TOLOWER ${lang} lang_lc) 6 file(REMOVE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin") 7 file(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" " 8 const char features[] = {\"\\n\"\n") 9 10 get_property(known_features GLOBAL PROPERTY CMAKE_${lang}_KNOWN_FEATURES) 11 12 foreach(feature ${known_features}) 13 if (_cmake_feature_test_${feature}) 14 if (${_cmake_feature_test_${feature}} STREQUAL 1) 15 set(_feature_condition "\"1\" ") 16 else() 17 set(_feature_condition "#if ${_cmake_feature_test_${feature}}\n\"1\"\n#else\n\"0\"\n#endif\n") 18 endif() 19 file(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" "\"${lang}_FEATURE:\"\n${_feature_condition}\"${feature}\\n\"\n") 20 endif() 21 endforeach() 22 file(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" 23 "\n};\n\nint main(int argc, char** argv) { (void)argv; return features[argc]; }\n") 24 25 if(CMAKE_${lang}_LINK_WITH_STANDARD_COMPILE_OPTION) 26 # This toolchain requires use of the language standard flag 27 # when linking in order to use the matching standard library. 28 set(compile_flags_for_link "${compile_flags}") 29 else() 30 set(compile_flags_for_link "") 31 endif() 32 33 try_compile(CMAKE_${lang}_FEATURE_TEST 34 ${CMAKE_BINARY_DIR} "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" 35 COMPILE_DEFINITIONS "${compile_flags}" 36 LINK_LIBRARIES "${compile_flags_for_link}" 37 OUTPUT_VARIABLE _output 38 COPY_FILE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin" 39 COPY_FILE_ERROR _copy_error 40 ) 41 if(CMAKE_${lang}_FEATURE_TEST AND NOT _copy_error) 42 set(_result 0) 43 else() 44 set(_result 255) 45 endif() 46 unset(CMAKE_${lang}_FEATURE_TEST CACHE) 47 unset(compile_flags_for_link) 48 49 if (_result EQUAL 0) 50 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log 51 "\n\nDetecting ${lang} [${compile_flags}] compiler features compiled with the following output:\n${_output}\n\n") 52 if(EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin") 53 file(STRINGS "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin" 54 features REGEX "${lang}_FEATURE:.*") 55 foreach(info ${features}) 56 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log 57 " Feature record: ${info}\n") 58 string(REPLACE "${lang}_FEATURE:" "" info ${info}) 59 string(SUBSTRING ${info} 0 1 has_feature) 60 if(has_feature) 61 string(REGEX REPLACE "^1" "" feature ${info}) 62 list(APPEND ${feature_list} ${feature}) 63 endif() 64 endforeach() 65 endif() 66 else() 67 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log 68 "Detecting ${lang} [${compile_flags}] compiler features failed to compile with the following output:\n${_output}\n${_copy_error}\n\n") 69 endif() 70endmacro() 71 72macro(_record_compiler_features_c std) 73 list(APPEND CMAKE_C${std}_COMPILE_FEATURES c_std_${std}) 74 75 get_property(lang_level_has_features GLOBAL PROPERTY CMAKE_C${std}_KNOWN_FEATURES) 76 if(lang_level_has_features) 77 _record_compiler_features(C "${CMAKE_C${std}_STANDARD_COMPILE_OPTION}" CMAKE_C${std}_COMPILE_FEATURES) 78 endif() 79 unset(lang_level_has_features) 80endmacro() 81 82macro(_record_compiler_features_cxx std) 83 list(APPEND CMAKE_CXX${std}_COMPILE_FEATURES cxx_std_${std}) 84 85 get_property(lang_level_has_features GLOBAL PROPERTY CMAKE_CXX${std}_KNOWN_FEATURES) 86 if(lang_level_has_features) 87 _record_compiler_features(CXX "${CMAKE_CXX${std}_STANDARD_COMPILE_OPTION}" CMAKE_CXX${std}_COMPILE_FEATURES) 88 endif() 89 unset(lang_level_has_features) 90endmacro() 91 92macro(_record_compiler_features_cuda std) 93 list(APPEND CMAKE_CUDA${std}_COMPILE_FEATURES cuda_std_${std}) 94 95 get_property(lang_level_has_features GLOBAL PROPERTY CMAKE_CUDA${std}_KNOWN_FEATURES) 96 if(lang_level_has_features) 97 _record_compiler_features(CUDA "${CMAKE_CUDA${std}_STANDARD_COMPILE_OPTION}" CMAKE_CUDA${std}_COMPILE_FEATURES) 98 endif() 99 unset(lang_level_has_features) 100endmacro() 101 102macro(_record_compiler_features_hip std) 103 list(APPEND CMAKE_HIP${std}_COMPILE_FEATURES hip_std_${std}) 104 105 get_property(lang_level_has_features GLOBAL PROPERTY CMAKE_HIP${std}_KNOWN_FEATURES) 106 if(lang_level_has_features) 107 _record_compiler_features(HIP "${CMAKE_HIP${std}_STANDARD_COMPILE_OPTION}" CMAKE_HIP${std}_COMPILE_FEATURES) 108 endif() 109 unset(lang_level_has_features) 110endmacro() 111 112macro(_has_compiler_features lang level compile_flags feature_list) 113 # presume all known features are supported 114 get_property(known_features GLOBAL PROPERTY CMAKE_${lang}${level}_KNOWN_FEATURES) 115 list(APPEND ${feature_list} ${known_features}) 116endmacro() 117 118macro(_has_compiler_features_c std) 119 list(APPEND CMAKE_C${std}_COMPILE_FEATURES c_std_${std}) 120 _has_compiler_features(C ${std} "${CMAKE_C${std}_STANDARD_COMPILE_OPTION}" CMAKE_C${std}_COMPILE_FEATURES) 121endmacro() 122macro(_has_compiler_features_cxx std) 123 list(APPEND CMAKE_CXX${std}_COMPILE_FEATURES cxx_std_${std}) 124 _has_compiler_features(CXX ${std} "${CMAKE_CXX${std}_STANDARD_COMPILE_OPTION}" CMAKE_CXX${std}_COMPILE_FEATURES) 125endmacro() 126macro(_has_compiler_features_cuda std) 127 list(APPEND CMAKE_CUDA${std}_COMPILE_FEATURES cuda_std_${std}) 128 _has_compiler_features(CUDA ${std} "${CMAKE_CUDA${std}_STANDARD_COMPILE_OPTION}" CMAKE_CUDA${std}_COMPILE_FEATURES) 129endmacro() 130macro(_has_compiler_features_hip std) 131 list(APPEND CMAKE_HIP${std}_COMPILE_FEATURES hip_std_${std}) 132 _has_compiler_features(HIP ${std} "${CMAKE_HIP${std}_STANDARD_COMPILE_OPTION}" CMAKE_HIP${std}_COMPILE_FEATURES) 133endmacro() 134