CMakeLists.txt 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. cmake_minimum_required(VERSION 3.1)
  2. project(CompileFeatures)
  3. if (NOT CMAKE_C_COMPILE_FEATURES AND NOT CMAKE_CXX_COMPILE_FEATURES)
  4. file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp"
  5. "int main(int,char**) { return 0; }\n"
  6. )
  7. add_executable(CompileFeatures "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp")
  8. return()
  9. endif()
  10. macro(run_test feature lang)
  11. if (";${CMAKE_${lang}_COMPILE_FEATURES};" MATCHES ${feature})
  12. add_library(test_${feature} OBJECT ${feature})
  13. set_property(TARGET test_${feature}
  14. PROPERTY COMPILE_FEATURES "${feature}"
  15. )
  16. else()
  17. list(APPEND ${lang}_non_features ${feature})
  18. endif()
  19. endmacro()
  20. get_property(c_features GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES)
  21. foreach(feature ${c_features})
  22. run_test(${feature} C)
  23. endforeach()
  24. get_property(cxx_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
  25. foreach(feature ${cxx_features})
  26. run_test(${feature} CXX)
  27. endforeach()
  28. if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"
  29. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)
  30. # AppleClang prior to 5.1 does not set any preprocessor define to distinguish
  31. # c++1y from c++11, so CMake does not support c++1y features before AppleClang 5.1.
  32. list(REMOVE_ITEM CXX_non_features
  33. cxx_attribute_deprecated
  34. cxx_binary_literals
  35. )
  36. endif()
  37. if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"
  38. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.2)
  39. # AppleClang prior to 4.1 reports false for __has_feature(cxx_local_type_template_args)
  40. # and __has_feature(cxx_unrestricted_unions) but it happens to pass these tests.
  41. list(REMOVE_ITEM CXX_non_features
  42. cxx_local_type_template_args
  43. cxx_unrestricted_unions
  44. )
  45. endif()
  46. if (CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
  47. list(REMOVE_ITEM CXX_non_features
  48. cxx_attribute_deprecated
  49. cxx_contextual_conversions
  50. cxx_extended_friend_declarations
  51. cxx_long_long_type
  52. cxx_sizeof_member
  53. cxx_variadic_macros
  54. )
  55. endif()
  56. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  57. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
  58. # The cxx_constexpr feature happens to work (for *this* testcase) with
  59. # GNU 4.5, but it is first documented as available with GNU 4.6.
  60. list(REMOVE_ITEM CXX_non_features
  61. cxx_constexpr
  62. )
  63. endif()
  64. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  65. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
  66. # The cxx_alignof feature happens to work (for *this* testcase) with
  67. # GNU 4.7, but it is first documented as available with GNU 4.8.
  68. list(REMOVE_ITEM CXX_non_features
  69. cxx_alignof
  70. )
  71. endif()
  72. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  73. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
  74. # GNU prior to 4.9 does not set any preprocessor define to distinguish
  75. # c++1y from c++11, so CMake does not support c++1y features before GNU 4.9.
  76. list(REMOVE_ITEM CXX_non_features
  77. # GNU 4.8 knows cxx_attributes, but doesn't know [[deprecated]]
  78. # and warns that it is unknown and ignored.
  79. cxx_attribute_deprecated
  80. cxx_binary_literals
  81. cxx_lambda_init_captures
  82. cxx_return_type_deduction
  83. )
  84. endif()
  85. set(C_ext c)
  86. set(C_standard_flag 11)
  87. set(CXX_ext cpp)
  88. set(CXX_standard_flag 14)
  89. foreach(lang CXX C)
  90. if (CMAKE_${lang}_COMPILE_FEATURES)
  91. foreach(feature ${${lang}_non_features})
  92. message("Testing feature : ${feature}")
  93. try_compile(${feature}_works
  94. "${CMAKE_CURRENT_BINARY_DIR}/${feature}_test"
  95. "${CMAKE_CURRENT_SOURCE_DIR}/feature_test.${${lang}_ext}"
  96. COMPILE_DEFINITIONS "-DTEST=${feature}.${${lang}_ext}"
  97. CMAKE_FLAGS "-DCMAKE_${lang}_STANDARD=${${lang}_standard_flag}"
  98. "-DINCLUDE_DIRECTORIES=${CMAKE_CURRENT_SOURCE_DIR}"
  99. OUTPUT_VARIABLE OUTPUT
  100. )
  101. if (${feature}_works)
  102. message(SEND_ERROR
  103. "Feature ${feature} expected not to work for ${lang} ${CMAKE_${lang}_COMPILER_ID}-${CMAKE_${lang}_COMPILER_VERSION}.
  104. Update the supported features or blacklist it.\n${OUTPUT}")
  105. else()
  106. message("Testing feature : ${feature} -- Fails, as expected.")
  107. endif()
  108. endforeach()
  109. endif()
  110. endforeach()
  111. if (CMAKE_C_COMPILE_FEATURES)
  112. string(FIND "${CMAKE_C_FLAGS}" "-std=" std_flag_idx)
  113. if (std_flag_idx EQUAL -1)
  114. add_executable(default_dialect_C default_dialect.c)
  115. target_compile_definitions(default_dialect_C PRIVATE
  116. DEFAULT_C11=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},11>
  117. DEFAULT_C99=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},99>
  118. DEFAULT_C90=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},90>
  119. )
  120. endif()
  121. endif()
  122. if (CMAKE_CXX_COMPILE_FEATURES)
  123. string(FIND "${CMAKE_CXX_FLAGS}" "-std=" std_flag_idx)
  124. if (std_flag_idx EQUAL -1)
  125. add_executable(default_dialect default_dialect.cpp)
  126. target_compile_definitions(default_dialect PRIVATE
  127. DEFAULT_CXX14=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},14>
  128. DEFAULT_CXX11=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},11>
  129. DEFAULT_CXX98=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},98>
  130. )
  131. endif()
  132. add_executable(CompileFeatures main.cpp)
  133. set_property(TARGET CompileFeatures
  134. PROPERTY COMPILE_FEATURES "cxx_auto_type"
  135. )
  136. set_property(TARGET CompileFeatures
  137. PROPERTY CXX_STANDARD_REQUIRED TRUE
  138. )
  139. add_executable(GenexCompileFeatures main.cpp)
  140. set_property(TARGET GenexCompileFeatures
  141. PROPERTY COMPILE_FEATURES "$<1:cxx_auto_type>;$<0:not_a_feature>"
  142. )
  143. add_library(iface INTERFACE)
  144. set_property(TARGET iface
  145. PROPERTY INTERFACE_COMPILE_FEATURES "cxx_auto_type"
  146. )
  147. add_executable(IfaceCompileFeatures main.cpp)
  148. target_link_libraries(IfaceCompileFeatures iface)
  149. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  150. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
  151. add_definitions(
  152. -DEXPECT_OVERRIDE_CONTROL=1
  153. -DEXPECT_INHERITING_CONSTRUCTORS=1
  154. -DEXPECT_FINAL=1
  155. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  156. )
  157. elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
  158. add_definitions(
  159. -DEXPECT_OVERRIDE_CONTROL=1
  160. -DEXPECT_INHERITING_CONSTRUCTORS=0
  161. -DEXPECT_FINAL=1
  162. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  163. )
  164. else()
  165. add_definitions(
  166. -DEXPECT_OVERRIDE_CONTROL=0
  167. -DEXPECT_INHERITING_CONSTRUCTORS=0
  168. -DEXPECT_FINAL=0
  169. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  170. )
  171. endif()
  172. elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  173. add_definitions(
  174. -DEXPECT_OVERRIDE_CONTROL=1
  175. -DEXPECT_INHERITING_CONSTRUCTORS=1
  176. -DEXPECT_FINAL=1
  177. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  178. )
  179. elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
  180. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
  181. add_definitions(
  182. -DEXPECT_OVERRIDE_CONTROL=1
  183. -DEXPECT_INHERITING_CONSTRUCTORS=1
  184. -DEXPECT_FINAL=1
  185. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  186. )
  187. else()
  188. add_definitions(
  189. -DEXPECT_OVERRIDE_CONTROL=1
  190. -DEXPECT_INHERITING_CONSTRUCTORS=0
  191. -DEXPECT_FINAL=1
  192. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  193. )
  194. endif()
  195. elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
  196. add_definitions(
  197. -DEXPECT_OVERRIDE_CONTROL=1
  198. -DEXPECT_INHERITING_CONSTRUCTORS=1
  199. -DEXPECT_FINAL=1
  200. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  201. )
  202. endif()
  203. add_executable(CompileFeaturesGenex genex_test.cpp)
  204. set_property(TARGET CompileFeaturesGenex PROPERTY CXX_STANDARD 11)
  205. target_compile_definitions(CompileFeaturesGenex PRIVATE
  206. HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
  207. HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
  208. HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
  209. HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
  210. HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
  211. )
  212. add_executable(CompileFeaturesGenex2 genex_test.cpp)
  213. target_compile_features(CompileFeaturesGenex2 PRIVATE cxx_static_assert)
  214. target_compile_definitions(CompileFeaturesGenex2 PRIVATE
  215. HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
  216. HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
  217. HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
  218. HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
  219. HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
  220. )
  221. add_library(static_assert_iface INTERFACE)
  222. target_compile_features(static_assert_iface INTERFACE cxx_static_assert)
  223. add_executable(CompileFeaturesGenex3 genex_test.cpp)
  224. target_link_libraries(CompileFeaturesGenex3 PRIVATE static_assert_iface)
  225. target_compile_definitions(CompileFeaturesGenex3 PRIVATE
  226. HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
  227. HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
  228. HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
  229. HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
  230. HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
  231. )
  232. endif()