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