FeatureTesting.cmake 5.5 KB

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