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