FeatureTesting.cmake 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. file(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" "
  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. file(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" "\"${lang}_FEATURE:\"\n${_feature_condition}\"${feature}\\n\"\n")
  16. endif()
  17. endforeach()
  18. file(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}"
  19. "\n};\n\nint main(int argc, char** argv) { (void)argv; return features[argc]; }\n")
  20. if(CMAKE_${lang}_LINK_WITH_STANDARD_COMPILE_OPTION)
  21. # This toolchain requires use of the language standard flag
  22. # when linking in order to use the matching standard library.
  23. set(compile_flags_for_link "${compile_flags}")
  24. else()
  25. set(compile_flags_for_link "")
  26. endif()
  27. try_compile(CMAKE_${lang}_FEATURE_TEST
  28. ${CMAKE_BINARY_DIR} "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}"
  29. COMPILE_DEFINITIONS "${compile_flags}"
  30. LINK_LIBRARIES "${compile_flags_for_link}"
  31. OUTPUT_VARIABLE _output
  32. COPY_FILE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin"
  33. COPY_FILE_ERROR _copy_error
  34. )
  35. if(CMAKE_${lang}_FEATURE_TEST AND NOT _copy_error)
  36. set(_result 0)
  37. else()
  38. set(_result 255)
  39. endif()
  40. unset(CMAKE_${lang}_FEATURE_TEST CACHE)
  41. unset(compile_flags_for_link)
  42. if (_result EQUAL 0)
  43. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
  44. "\n\nDetecting ${lang} [${compile_flags}] compiler features compiled with the following output:\n${_output}\n\n")
  45. if(EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin")
  46. file(STRINGS "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin"
  47. features REGEX "${lang}_FEATURE:.*")
  48. foreach(info ${features})
  49. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
  50. " Feature record: ${info}\n")
  51. string(REPLACE "${lang}_FEATURE:" "" info ${info})
  52. string(SUBSTRING ${info} 0 1 has_feature)
  53. if(has_feature)
  54. string(REGEX REPLACE "^1" "" feature ${info})
  55. list(APPEND ${feature_list} ${feature})
  56. endif()
  57. endforeach()
  58. endif()
  59. else()
  60. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
  61. "Detecting ${lang} [${compile_flags}] compiler features failed to compile with the following output:\n${_output}\n${_copy_error}\n\n")
  62. endif()
  63. endmacro()
  64. macro(_record_compiler_features_c std)
  65. list(APPEND CMAKE_C${std}_COMPILE_FEATURES c_std_${std})
  66. _record_compiler_features(C "${CMAKE_C${std}_STANDARD_COMPILE_OPTION}" CMAKE_C${std}_COMPILE_FEATURES)
  67. endmacro()
  68. macro(_record_compiler_features_cxx std)
  69. list(APPEND CMAKE_CXX${std}_COMPILE_FEATURES cxx_std_${std})
  70. _record_compiler_features(CXX "${CMAKE_CXX${std}_STANDARD_COMPILE_OPTION}" CMAKE_CXX${std}_COMPILE_FEATURES)
  71. endmacro()