CMakeLists.txt 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  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. list(REMOVE_ITEM c_features c_std_90 c_std_99 c_std_11)
  22. foreach(feature ${c_features})
  23. run_test(${feature} C)
  24. endforeach()
  25. get_property(cxx_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
  26. list(REMOVE_ITEM cxx_features cxx_std_98 cxx_std_11 cxx_std_14 cxx_std_17)
  27. foreach(feature ${cxx_features})
  28. run_test(${feature} CXX)
  29. endforeach()
  30. if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"
  31. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)
  32. # AppleClang prior to 5.1 does not set any preprocessor define to distinguish
  33. # c++1y from c++11, so CMake does not support c++1y features before AppleClang 5.1.
  34. list(REMOVE_ITEM CXX_non_features
  35. cxx_attribute_deprecated
  36. cxx_binary_literals
  37. )
  38. endif()
  39. if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"
  40. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.2)
  41. # AppleClang prior to 4.1 reports false for __has_feature(cxx_local_type_template_args)
  42. # and __has_feature(cxx_unrestricted_unions) but it happens to pass these tests.
  43. list(REMOVE_ITEM CXX_non_features
  44. cxx_local_type_template_args
  45. cxx_unrestricted_unions
  46. )
  47. endif()
  48. if (CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
  49. list(REMOVE_ITEM CXX_non_features
  50. cxx_attribute_deprecated
  51. cxx_contextual_conversions
  52. cxx_extended_friend_declarations
  53. cxx_long_long_type
  54. cxx_sizeof_member
  55. cxx_variadic_macros
  56. )
  57. endif()
  58. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  59. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.5)
  60. # The cxx_raw_string_literals feature happens to work in some distributions
  61. # of GNU 4.4, but it is first documented as available with GNU 4.5.
  62. list(REMOVE_ITEM CXX_non_features
  63. cxx_raw_string_literals
  64. )
  65. endif()
  66. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  67. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
  68. # The cxx_constexpr feature happens to work (for *this* testcase) with
  69. # GNU 4.5, but it is first documented as available with GNU 4.6.
  70. list(REMOVE_ITEM CXX_non_features
  71. cxx_constexpr
  72. )
  73. endif()
  74. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  75. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
  76. # The cxx_alignof feature happens to work (for *this* testcase) with
  77. # GNU 4.7, but it is first documented as available with GNU 4.8.
  78. list(REMOVE_ITEM CXX_non_features
  79. cxx_alignof
  80. )
  81. endif()
  82. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  83. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
  84. # GNU prior to 4.9 does not set any preprocessor define to distinguish
  85. # c++1y from c++11, so CMake does not support c++1y features before GNU 4.9.
  86. list(REMOVE_ITEM CXX_non_features
  87. # GNU 4.8 knows cxx_attributes, but doesn't know [[deprecated]]
  88. # and warns that it is unknown and ignored.
  89. cxx_attribute_deprecated
  90. cxx_binary_literals
  91. cxx_lambda_init_captures
  92. cxx_return_type_deduction
  93. )
  94. endif()
  95. if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  96. if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0)
  97. list(REMOVE_ITEM CXX_non_features
  98. # The cxx_contextual_conversions feature happens to work
  99. # (for *this* testcase) with VS 2010 and VS 2012, but
  100. # they do not document support until VS 2013.
  101. cxx_contextual_conversions
  102. )
  103. elseif (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0)
  104. list(REMOVE_ITEM CXX_non_features
  105. # The cxx_deleted_functions and cxx_nonstatic_member_init
  106. # features happen to work (for *this* testcase) with VS 2013,
  107. # but they do not document support until VS 2015.
  108. cxx_deleted_functions
  109. cxx_nonstatic_member_init
  110. )
  111. endif()
  112. endif()
  113. if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
  114. if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16.0)
  115. if (CMAKE_CXX_COMIPLER_VERSION VERSION_EQUAL 15.0)
  116. list(REMOVE_ITEM CXX_non_features
  117. # The cxx_contextual_conversions feature happens to work
  118. # (for *this* testcase) with Intel 13/14/15, but they do not
  119. # document support until 16.
  120. cxx_contextual_conversions
  121. )
  122. elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14.0)
  123. list(REMOVE_ITEM CXX_non_features
  124. cxx_alignof
  125. # not supposed to work until 15
  126. cxx_attribute_deprecated
  127. # The cxx_contextual_conversions feature happens to work
  128. # (for *this* testcase) with Intel 13/14/15, but they do not
  129. # document support until 16.
  130. cxx_contextual_conversions
  131. )
  132. elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.1)
  133. list(REMOVE_ITEM CXX_non_features
  134. # These features happen to work but aren't documented to
  135. # do so until 14.0
  136. cxx_constexpr
  137. cxx_enum_forward_declarations
  138. cxx_sizeof_member
  139. cxx_strong_enums
  140. cxx_unicode_literals
  141. # not supposed to work until 15
  142. cxx_attribute_deprecated
  143. cxx_nonstatic_member_init
  144. # The cxx_contextual_conversions feature happens to work
  145. # (for *this* testcase) with Intel 13/14/15, but they do not
  146. # document support until 16.
  147. cxx_contextual_conversions
  148. # This is an undocumented feature; it does not work in future versions
  149. cxx_aggregate_default_initializers
  150. )
  151. endif()
  152. endif()
  153. endif()
  154. if (CMAKE_C_COMPILER_ID STREQUAL "Intel")
  155. if (CMAKE_C_COMPILER_VERSION VERSION_LESS 15.0.2)
  156. # This works on some pre-15.0.2 versions and not others.
  157. list(REMOVE_ITEM C_non_features
  158. c_static_assert
  159. )
  160. endif()
  161. endif()
  162. set(C_ext c)
  163. set(C_standard_flag 11)
  164. set(CXX_ext cpp)
  165. set(CXX_standard_flag 14)
  166. foreach(lang CXX C)
  167. if (CMAKE_${lang}_COMPILE_FEATURES)
  168. foreach(feature ${${lang}_non_features})
  169. message("Testing feature : ${feature}")
  170. try_compile(${feature}_works
  171. "${CMAKE_CURRENT_BINARY_DIR}/${feature}_test"
  172. "${CMAKE_CURRENT_SOURCE_DIR}/feature_test.${${lang}_ext}"
  173. COMPILE_DEFINITIONS "-DTEST=${feature}.${${lang}_ext}"
  174. CMAKE_FLAGS "-DCMAKE_${lang}_STANDARD=${${lang}_standard_flag}"
  175. "-DINCLUDE_DIRECTORIES=${CMAKE_CURRENT_SOURCE_DIR}"
  176. OUTPUT_VARIABLE OUTPUT
  177. )
  178. if (${feature}_works)
  179. message(SEND_ERROR
  180. "Feature ${feature} expected not to work for ${lang} ${CMAKE_${lang}_COMPILER_ID}-${CMAKE_${lang}_COMPILER_VERSION}.
  181. Update the supported features or blacklist it.\n${OUTPUT}")
  182. else()
  183. message("Testing feature : ${feature} -- Fails, as expected.")
  184. endif()
  185. endforeach()
  186. endif()
  187. endforeach()
  188. if (CMAKE_C_COMPILE_FEATURES)
  189. if (CMAKE_C_STANDARD_DEFAULT)
  190. string(FIND "${CMAKE_C_FLAGS}" "-std=" std_flag_idx)
  191. if (std_flag_idx EQUAL -1)
  192. add_executable(default_dialect_C default_dialect.c)
  193. target_compile_definitions(default_dialect_C PRIVATE
  194. DEFAULT_C11=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},11>
  195. DEFAULT_C99=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},99>
  196. DEFAULT_C90=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},90>
  197. )
  198. endif()
  199. endif()
  200. add_executable(CompileFeaturesGenex_C genex_test.c)
  201. set_property(TARGET CompileFeaturesGenex_C PROPERTY C_STANDARD 11)
  202. if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
  203. if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6)
  204. list(APPEND expected_defs
  205. EXPECT_C_STATIC_ASSERT=1
  206. )
  207. else()
  208. list(APPEND expected_defs
  209. EXPECT_C_STATIC_ASSERT=0
  210. )
  211. endif()
  212. elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang"
  213. OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
  214. list(APPEND expected_defs
  215. EXPECT_C_STATIC_ASSERT=1
  216. )
  217. elseif (CMAKE_C_COMPILER_ID STREQUAL "Intel")
  218. if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 15)
  219. list(APPEND expected_defs
  220. EXPECT_C_STATIC_ASSERT=1
  221. )
  222. else()
  223. list(APPEND expected_defs
  224. EXPECT_C_STATIC_ASSERT=0
  225. )
  226. endif()
  227. endif()
  228. list(APPEND expected_defs
  229. EXPECT_C_FUNCTION_PROTOTYPES=1
  230. EXPECT_C_RESTRICT=1
  231. )
  232. target_compile_definitions(CompileFeaturesGenex_C PRIVATE
  233. HAVE_C_FUNCTION_PROTOTYPES=$<COMPILE_FEATURES:c_function_prototypes>
  234. HAVE_C_RESTRICT=$<COMPILE_FEATURES:c_restrict>
  235. HAVE_C_STATIC_ASSERT=$<COMPILE_FEATURES:c_static_assert>
  236. ${expected_defs}
  237. )
  238. endif()
  239. if (CMAKE_CXX_COMPILE_FEATURES)
  240. if (CMAKE_CXX_STANDARD_DEFAULT)
  241. string(FIND "${CMAKE_CXX_FLAGS}" "-std=" std_flag_idx)
  242. if (std_flag_idx EQUAL -1)
  243. add_executable(default_dialect default_dialect.cpp)
  244. target_compile_definitions(default_dialect PRIVATE
  245. DEFAULT_CXX17=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},17>
  246. DEFAULT_CXX14=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},14>
  247. DEFAULT_CXX11=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},11>
  248. DEFAULT_CXX98=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},98>
  249. )
  250. endif()
  251. endif()
  252. add_executable(CompileFeatures main.cpp)
  253. set_property(TARGET CompileFeatures
  254. PROPERTY COMPILE_FEATURES "cxx_auto_type"
  255. )
  256. set_property(TARGET CompileFeatures
  257. PROPERTY CXX_STANDARD_REQUIRED TRUE
  258. )
  259. add_executable(GenexCompileFeatures main.cpp)
  260. set_property(TARGET GenexCompileFeatures
  261. PROPERTY COMPILE_FEATURES "$<1:cxx_auto_type>;$<0:not_a_feature>"
  262. )
  263. add_library(iface INTERFACE)
  264. set_property(TARGET iface
  265. PROPERTY INTERFACE_COMPILE_FEATURES "cxx_auto_type"
  266. )
  267. add_executable(IfaceCompileFeatures main.cpp)
  268. target_link_libraries(IfaceCompileFeatures iface)
  269. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  270. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
  271. add_definitions(
  272. -DEXPECT_OVERRIDE_CONTROL=1
  273. -DEXPECT_INHERITING_CONSTRUCTORS=1
  274. -DEXPECT_FINAL=1
  275. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  276. )
  277. elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
  278. add_definitions(
  279. -DEXPECT_OVERRIDE_CONTROL=1
  280. -DEXPECT_INHERITING_CONSTRUCTORS=0
  281. -DEXPECT_FINAL=1
  282. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  283. )
  284. else()
  285. add_definitions(
  286. -DEXPECT_OVERRIDE_CONTROL=0
  287. -DEXPECT_INHERITING_CONSTRUCTORS=0
  288. -DEXPECT_FINAL=0
  289. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  290. )
  291. endif()
  292. elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  293. add_definitions(
  294. -DEXPECT_OVERRIDE_CONTROL=1
  295. -DEXPECT_INHERITING_CONSTRUCTORS=1
  296. -DEXPECT_FINAL=1
  297. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  298. )
  299. elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
  300. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
  301. add_definitions(
  302. -DEXPECT_OVERRIDE_CONTROL=1
  303. -DEXPECT_INHERITING_CONSTRUCTORS=1
  304. -DEXPECT_FINAL=1
  305. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  306. )
  307. else()
  308. add_definitions(
  309. -DEXPECT_OVERRIDE_CONTROL=1
  310. -DEXPECT_INHERITING_CONSTRUCTORS=0
  311. -DEXPECT_FINAL=1
  312. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  313. )
  314. endif()
  315. elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  316. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0)
  317. add_definitions(
  318. -DEXPECT_OVERRIDE_CONTROL=1
  319. -DEXPECT_INHERITING_CONSTRUCTORS=1
  320. -DEXPECT_FINAL=1
  321. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  322. )
  323. elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17.0)
  324. add_definitions(
  325. -DEXPECT_OVERRIDE_CONTROL=1
  326. -DEXPECT_INHERITING_CONSTRUCTORS=0
  327. -DEXPECT_FINAL=1
  328. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  329. )
  330. else()
  331. add_definitions(
  332. -DEXPECT_OVERRIDE_CONTROL=0
  333. -DEXPECT_INHERITING_CONSTRUCTORS=0
  334. -DEXPECT_FINAL=0
  335. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  336. )
  337. endif()
  338. elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
  339. add_definitions(
  340. -DEXPECT_OVERRIDE_CONTROL=1
  341. -DEXPECT_INHERITING_CONSTRUCTORS=1
  342. -DEXPECT_FINAL=1
  343. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  344. )
  345. elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
  346. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15)
  347. add_definitions(
  348. -DEXPECT_OVERRIDE_CONTROL=1
  349. -DEXPECT_INHERITING_CONSTRUCTORS=1
  350. -DEXPECT_FINAL=1
  351. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
  352. )
  353. elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14)
  354. add_definitions(
  355. -DEXPECT_OVERRIDE_CONTROL=1
  356. -DEXPECT_INHERITING_CONSTRUCTORS=0
  357. -DEXPECT_FINAL=1
  358. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  359. )
  360. else()
  361. add_definitions(
  362. -DEXPECT_OVERRIDE_CONTROL=0
  363. -DEXPECT_INHERITING_CONSTRUCTORS=0
  364. -DEXPECT_FINAL=0
  365. -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
  366. )
  367. endif()
  368. endif()
  369. add_executable(CompileFeaturesGenex genex_test.cpp)
  370. set_property(TARGET CompileFeaturesGenex PROPERTY CXX_STANDARD 11)
  371. target_compile_definitions(CompileFeaturesGenex PRIVATE
  372. HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
  373. HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
  374. HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
  375. HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
  376. HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
  377. )
  378. add_executable(CompileFeaturesGenex2 genex_test.cpp)
  379. target_compile_features(CompileFeaturesGenex2 PRIVATE cxx_std_11)
  380. target_compile_definitions(CompileFeaturesGenex2 PRIVATE
  381. HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
  382. HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
  383. HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
  384. HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
  385. HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
  386. )
  387. add_library(std_11_iface INTERFACE)
  388. target_compile_features(std_11_iface INTERFACE cxx_std_11)
  389. add_executable(CompileFeaturesGenex3 genex_test.cpp)
  390. target_link_libraries(CompileFeaturesGenex3 PRIVATE std_11_iface)
  391. target_compile_definitions(CompileFeaturesGenex3 PRIVATE
  392. HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
  393. HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
  394. HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
  395. HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
  396. HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
  397. )
  398. endif()