PageRenderTime 61ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/Tests/CompileFeatures/CMakeLists.txt

https://github.com/dlrdave/CMake
CMake | 375 lines | 300 code | 35 blank | 40 comment | 36 complexity | 68a799adfadcbed098490483a5165a97 MD5 | raw file
  1. cmake_minimum_required(VERSION 3.1)
  2. cmake_policy(SET CMP0057 NEW)
  3. project(CompileFeatures)
  4. set(ext_C c)
  5. set(ext_CXX cpp)
  6. macro(run_test feature lang)
  7. if (${feature} IN_LIST CMAKE_${lang}_COMPILE_FEATURES)
  8. add_library(test_${feature} OBJECT ${feature}.${ext_${lang}})
  9. set_property(TARGET test_${feature}
  10. PROPERTY COMPILE_FEATURES "${feature}"
  11. )
  12. else()
  13. list(APPEND ${lang}_non_features ${feature})
  14. endif()
  15. endmacro()
  16. if(NOT CMAKE_C_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IBMClang|IntelLLVM|Fujitsu|FujitsuClang)$")
  17. get_property(c_features GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES)
  18. list(FILTER c_features EXCLUDE REGEX "^c_std_[0-9][0-9]")
  19. foreach(feature ${c_features})
  20. run_test(${feature} C)
  21. endforeach()
  22. endif()
  23. if(NOT CMAKE_CXX_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IBMClang|IntelLLVM|Fujitsu|FujitsuClang)$")
  24. get_property(cxx_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
  25. list(FILTER cxx_features EXCLUDE REGEX "^cxx_std_[0-9][0-9]")
  26. foreach(feature ${cxx_features})
  27. run_test(${feature} CXX)
  28. endforeach()
  29. endif()
  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. if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.15)
  50. # SunPro 5.14 accepts -std=c++14 and compiles two features but does
  51. # not define __cplusplus to a value different than with -std=c++11.
  52. list(REMOVE_ITEM CXX_non_features
  53. cxx_aggregate_default_initializers
  54. cxx_digit_separators
  55. )
  56. endif()
  57. # FIXME: Do any of these work correctly on SunPro 5.13 or above?
  58. list(REMOVE_ITEM CXX_non_features
  59. cxx_attribute_deprecated
  60. cxx_contextual_conversions
  61. cxx_extended_friend_declarations
  62. cxx_long_long_type
  63. cxx_sizeof_member
  64. cxx_variadic_macros
  65. )
  66. endif()
  67. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  68. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.5)
  69. # The cxx_raw_string_literals feature happens to work in some distributions
  70. # of GNU 4.4, but it is first documented as available with GNU 4.5.
  71. list(REMOVE_ITEM CXX_non_features
  72. cxx_raw_string_literals
  73. )
  74. endif()
  75. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  76. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
  77. # The cxx_constexpr feature happens to work (for *this* testcase) with
  78. # GNU 4.5, but it is first documented as available with GNU 4.6.
  79. list(REMOVE_ITEM CXX_non_features
  80. cxx_constexpr
  81. )
  82. endif()
  83. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  84. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
  85. # The cxx_alignof feature happens to work (for *this* testcase) with
  86. # GNU 4.7, but it is first documented as available with GNU 4.8.
  87. list(REMOVE_ITEM CXX_non_features
  88. cxx_alignof
  89. )
  90. endif()
  91. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
  92. AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
  93. # GNU prior to 4.9 does not set any preprocessor define to distinguish
  94. # c++1y from c++11, so CMake does not support c++1y features before GNU 4.9.
  95. list(REMOVE_ITEM CXX_non_features
  96. # GNU 4.8 knows cxx_attributes, but doesn't know [[deprecated]]
  97. # and warns that it is unknown and ignored.
  98. cxx_attribute_deprecated
  99. cxx_binary_literals
  100. cxx_lambda_init_captures
  101. cxx_return_type_deduction
  102. )
  103. endif()
  104. if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  105. if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0)
  106. list(REMOVE_ITEM CXX_non_features
  107. # The cxx_contextual_conversions feature happens to work
  108. # (for *this* testcase) with VS 2010 and VS 2012, but
  109. # they do not document support until VS 2013.
  110. cxx_contextual_conversions
  111. )
  112. elseif (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0)
  113. list(REMOVE_ITEM CXX_non_features
  114. # The cxx_deleted_functions and cxx_nonstatic_member_init
  115. # features happen to work (for *this* testcase) with VS 2013,
  116. # but they do not document support until VS 2015.
  117. cxx_deleted_functions
  118. cxx_nonstatic_member_init
  119. )
  120. endif()
  121. endif()
  122. if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
  123. if (CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"
  124. AND CMAKE_CXX_SIMULATE_VERSION VERSION_LESS 19.10)
  125. list(REMOVE_ITEM CXX_non_features
  126. cxx_relaxed_constexpr
  127. )
  128. endif()
  129. if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16.0)
  130. if (CMAKE_CXX_COMIPLER_VERSION VERSION_EQUAL 15.0)
  131. list(REMOVE_ITEM CXX_non_features
  132. # The cxx_contextual_conversions feature happens to work
  133. # (for *this* testcase) with Intel 13/14/15, but they do not
  134. # document support until 16.
  135. cxx_contextual_conversions
  136. )
  137. elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14.0)
  138. list(REMOVE_ITEM CXX_non_features
  139. cxx_alignof
  140. # not supposed to work until 15
  141. cxx_attribute_deprecated
  142. # The cxx_contextual_conversions feature happens to work
  143. # (for *this* testcase) with Intel 13/14/15, but they do not
  144. # document support until 16.
  145. cxx_contextual_conversions
  146. )
  147. elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.1)
  148. list(REMOVE_ITEM CXX_non_features
  149. # These features happen to work but aren't documented to
  150. # do so until 14.0
  151. cxx_constexpr
  152. cxx_enum_forward_declarations
  153. cxx_sizeof_member
  154. cxx_strong_enums
  155. cxx_unicode_literals
  156. # not supposed to work until 15
  157. cxx_attribute_deprecated
  158. cxx_nonstatic_member_init
  159. # The cxx_contextual_conversions feature happens to work
  160. # (for *this* testcase) with Intel 13/14/15, but they do not
  161. # document support until 16.
  162. cxx_contextual_conversions
  163. # This is an undocumented feature; it does not work in future versions
  164. cxx_aggregate_default_initializers
  165. )
  166. endif()
  167. endif()
  168. endif()
  169. if (CMAKE_C_COMPILER_ID STREQUAL "Intel")
  170. if (CMAKE_C_COMPILER_VERSION VERSION_LESS 15.0.2)
  171. # This works on some pre-15.0.2 versions and not others.
  172. list(REMOVE_ITEM C_non_features
  173. c_static_assert
  174. )
  175. endif()
  176. endif()
  177. if (CMAKE_C_COMPILE_FEATURES)
  178. set(C_expected_features ${CMAKE_C_COMPILE_FEATURES})
  179. list(FILTER C_expected_features EXCLUDE REGEX "^c_std_[0-9][0-9]")
  180. endif()
  181. if (CMAKE_CXX_COMPILE_FEATURES)
  182. set(CXX_expected_features ${CMAKE_CXX_COMPILE_FEATURES})
  183. list(FILTER CXX_expected_features EXCLUDE REGEX "^cxx_std_[0-9][0-9]")
  184. endif ()
  185. set(C_ext c)
  186. set(C_standard_flag 11)
  187. set(CXX_ext cpp)
  188. set(CXX_standard_flag 14)
  189. foreach(lang CXX C)
  190. if (${lang}_expected_features)
  191. foreach(feature ${${lang}_non_features})
  192. message("Testing feature : ${feature}")
  193. try_compile(${feature}_works
  194. "${CMAKE_CURRENT_BINARY_DIR}/${feature}_test"
  195. "${CMAKE_CURRENT_SOURCE_DIR}/feature_test.${${lang}_ext}"
  196. COMPILE_DEFINITIONS "-DTEST=${feature}.${${lang}_ext}"
  197. CMAKE_FLAGS "-DCMAKE_${lang}_STANDARD=${${lang}_standard_flag}"
  198. "-DINCLUDE_DIRECTORIES=${CMAKE_CURRENT_SOURCE_DIR}"
  199. OUTPUT_VARIABLE OUTPUT
  200. )
  201. if (${feature}_works)
  202. message(SEND_ERROR
  203. "Feature ${feature} expected not to work for ${lang} ${CMAKE_${lang}_COMPILER_ID}-${CMAKE_${lang}_COMPILER_VERSION}.
  204. Update the supported features or blacklist it.\n${OUTPUT}")
  205. else()
  206. message("Testing feature : ${feature} -- Fails, as expected.")
  207. endif()
  208. endforeach()
  209. endif()
  210. endforeach()
  211. if (C_expected_features)
  212. if (CMAKE_C_STANDARD_DEFAULT)
  213. string(FIND "${CMAKE_C_FLAGS}" "-std=" std_flag_idx)
  214. if (std_flag_idx EQUAL -1)
  215. add_executable(default_dialect_C default_dialect.c)
  216. target_compile_definitions(default_dialect_C PRIVATE
  217. DEFAULT_C23=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},23>
  218. DEFAULT_C17=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},17>
  219. DEFAULT_C11=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},11>
  220. DEFAULT_C99=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},99>
  221. DEFAULT_C90=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},90>
  222. )
  223. endif()
  224. endif()
  225. add_executable(CompileFeaturesGenex_C genex_test.c)
  226. set_property(TARGET CompileFeaturesGenex_C PROPERTY C_STANDARD 11)
  227. foreach(f
  228. c_restrict
  229. c_static_assert
  230. c_function_prototypes
  231. )
  232. if(${f} IN_LIST C_expected_features)
  233. set(expect_${f} 1)
  234. else()
  235. set(expect_${f} 0)
  236. endif()
  237. string(TOUPPER "${f}" F)
  238. target_compile_definitions(CompileFeaturesGenex_C PRIVATE
  239. EXPECT_${F}=${expect_${f}}
  240. HAVE_${F}=$<COMPILE_FEATURES:${f}>
  241. )
  242. endforeach()
  243. endif()
  244. if (CMAKE_CXX_COMPILE_FEATURES)
  245. if (CMAKE_CXX_STANDARD_DEFAULT)
  246. string(FIND "${CMAKE_CXX_FLAGS}" "-std=" std_flag_idx)
  247. if (std_flag_idx EQUAL -1)
  248. add_executable(default_dialect default_dialect.cpp)
  249. target_compile_definitions(default_dialect PRIVATE
  250. DEFAULT_CXX23=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},23>
  251. DEFAULT_CXX20=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},20>
  252. DEFAULT_CXX17=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},17>
  253. DEFAULT_CXX14=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},14>
  254. DEFAULT_CXX11=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},11>
  255. DEFAULT_CXX98=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},98>
  256. )
  257. endif()
  258. endif()
  259. endif ()
  260. # always add a target "CompileFeatures"
  261. if ((NOT CXX_expected_features) OR
  262. (NOT cxx_auto_type IN_LIST CXX_expected_features))
  263. file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp"
  264. "int main(int,char**) { return 0; }\n"
  265. )
  266. add_executable(CompileFeatures "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp")
  267. else()
  268. # these tests only work if at least cxx_auto_type is available
  269. add_executable(CompileFeatures main.cpp)
  270. set_property(TARGET CompileFeatures
  271. PROPERTY COMPILE_FEATURES "cxx_auto_type"
  272. )
  273. set_property(TARGET CompileFeatures
  274. PROPERTY CXX_STANDARD_REQUIRED TRUE
  275. )
  276. add_executable(GenexCompileFeatures main.cpp)
  277. set_property(TARGET GenexCompileFeatures
  278. PROPERTY COMPILE_FEATURES "$<1:cxx_auto_type>;$<0:not_a_feature>"
  279. )
  280. add_library(iface INTERFACE)
  281. set_property(TARGET iface
  282. PROPERTY INTERFACE_COMPILE_FEATURES "cxx_auto_type"
  283. )
  284. add_executable(IfaceCompileFeatures main.cpp)
  285. target_link_libraries(IfaceCompileFeatures iface)
  286. foreach(f
  287. cxx_final
  288. cxx_override
  289. cxx_auto_type
  290. cxx_inheriting_constructors
  291. )
  292. if(${f} IN_LIST CXX_expected_features)
  293. set(expect_${f} 1)
  294. else()
  295. set(expect_${f} 0)
  296. endif()
  297. endforeach()
  298. if(expect_cxx_final AND expect_cxx_override)
  299. set(expect_override_control 1)
  300. else()
  301. set(expect_override_control 0)
  302. endif()
  303. if(expect_cxx_inheriting_constructors AND expect_cxx_final)
  304. set(expect_inheriting_constructors_and_final 1)
  305. else()
  306. set(expect_inheriting_constructors_and_final 0)
  307. endif()
  308. set(genex_test_defs
  309. HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
  310. HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
  311. HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
  312. HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
  313. HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
  314. EXPECT_OVERRIDE_CONTROL=${expect_override_control}
  315. EXPECT_INHERITING_CONSTRUCTORS=${expect_cxx_inheriting_constructors}
  316. EXPECT_FINAL=${expect_cxx_final}
  317. EXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=${expect_inheriting_constructors_and_final}
  318. )
  319. if (CMAKE_CXX_STANDARD_DEFAULT)
  320. list(APPEND genex_test_defs
  321. TEST_CXX_STD
  322. HAVE_CXX_STD_11=$<COMPILE_FEATURES:cxx_std_11>
  323. HAVE_CXX_STD_14=$<COMPILE_FEATURES:cxx_std_14>
  324. HAVE_CXX_STD_17=$<COMPILE_FEATURES:cxx_std_17>
  325. HAVE_CXX_STD_20=$<COMPILE_FEATURES:cxx_std_20>
  326. HAVE_CXX_STD_23=$<COMPILE_FEATURES:cxx_std_23>
  327. )
  328. endif()
  329. add_executable(CompileFeaturesGenex genex_test.cpp)
  330. set_property(TARGET CompileFeaturesGenex PROPERTY CXX_STANDARD 11)
  331. target_compile_definitions(CompileFeaturesGenex PRIVATE ${genex_test_defs})
  332. add_executable(CompileFeaturesGenex2 genex_test.cpp)
  333. target_compile_features(CompileFeaturesGenex2 PRIVATE cxx_std_11)
  334. target_compile_definitions(CompileFeaturesGenex2 PRIVATE ${genex_test_defs} ALLOW_LATER_STANDARDS=1)
  335. add_library(std_11_iface INTERFACE)
  336. target_compile_features(std_11_iface INTERFACE cxx_std_11)
  337. add_executable(CompileFeaturesGenex3 genex_test.cpp)
  338. target_link_libraries(CompileFeaturesGenex3 PRIVATE std_11_iface)
  339. target_compile_definitions(CompileFeaturesGenex3 PRIVATE ${genex_test_defs} ALLOW_LATER_STANDARDS=1)
  340. endif()