WriteCompilerDetectionHeader.cmake 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. #.rst:
  2. # WriteCompilerDetectionHeader
  3. # ----------------------------
  4. #
  5. # This module provides the function write_compiler_detection_header().
  6. #
  7. # The ``WRITE_COMPILER_DETECTION_HEADER`` function can be used to generate
  8. # a file suitable for preprocessor inclusion which contains macros to be
  9. # used in source code::
  10. #
  11. # write_compiler_detection_header(
  12. # FILE <file>
  13. # PREFIX <prefix>
  14. # COMPILERS <compiler> [...]
  15. # FEATURES <feature> [...]
  16. # [VERSION <version>]
  17. # [PROLOG <prolog>]
  18. # [EPILOG <epilog>]
  19. # )
  20. #
  21. # The ``write_compiler_detection_header`` function generates the
  22. # file ``<file>`` with macros which all have the prefix ``<prefix>``.
  23. #
  24. # ``VERSION`` may be used to specify the API version to be generated.
  25. # Future versions of CMake may introduce alternative APIs. A given
  26. # API is selected by any ``<version>`` value greater than or equal
  27. # to the version of CMake that introduced the given API and less
  28. # than the version of CMake that introduced its succeeding API.
  29. # The value of the :variable:`CMAKE_MINIMUM_REQUIRED_VERSION`
  30. # variable is used if no explicit version is specified.
  31. # (As of CMake version |release| there is only one API version.)
  32. #
  33. # ``PROLOG`` may be specified as text content to write at the start of the
  34. # header. ``EPILOG`` may be specified as text content to write at the end
  35. # of the header
  36. #
  37. # At least one ``<compiler>`` and one ``<feature>`` must be listed. Compilers
  38. # which are known to CMake, but not specified are detected and a preprocessor
  39. # ``#error`` is generated for them. A preprocessor macro matching
  40. # ``<PREFIX>_COMPILER_IS_<compiler>`` is generated for each compiler
  41. # known to CMake to contain the value ``0`` or ``1``.
  42. #
  43. # Possible compiler identifiers are documented with the
  44. # :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
  45. # Available features in this version of CMake are listed in the
  46. # :prop_gbl:`CMAKE_C_KNOWN_FEATURES` and
  47. # :prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global properties.
  48. #
  49. # See the :manual:`cmake-compile-features(7)` manual for information on
  50. # compile features.
  51. #
  52. # Feature Test Macros
  53. # ===================
  54. #
  55. # For each compiler, a preprocessor macro is generated matching
  56. # ``<PREFIX>_COMPILER_IS_<compiler>`` which has the content either ``0``
  57. # or ``1``, depending on the compiler in use. Preprocessor macros for
  58. # compiler version components are generated matching
  59. # ``<PREFIX>_COMPILER_VERSION_MAJOR`` ``<PREFIX>_COMPILER_VERSION_MINOR``
  60. # and ``<PREFIX>_COMPILER_VERSION_PATCH`` containing decimal values
  61. # for the corresponding compiler version components, if defined.
  62. #
  63. # A preprocessor test is generated based on the compiler version
  64. # denoting whether each feature is enabled. A preprocessor macro
  65. # matching ``<PREFIX>_COMPILER_<FEATURE>``, where ``<FEATURE>`` is the
  66. # upper-case ``<feature>`` name, is generated to contain the value
  67. # ``0`` or ``1`` depending on whether the compiler in use supports the
  68. # feature:
  69. #
  70. # .. code-block:: cmake
  71. #
  72. # write_compiler_detection_header(
  73. # FILE climbingstats_compiler_detection.h
  74. # PREFIX ClimbingStats
  75. # COMPILERS GNU Clang MSVC
  76. # FEATURES cxx_variadic_templates
  77. # )
  78. #
  79. # .. code-block:: c++
  80. #
  81. # #if ClimbingStats_COMPILER_CXX_VARIADIC_TEMPLATES
  82. # template<typename... T>
  83. # void someInterface(T t...) { /* ... */ }
  84. # #else
  85. # // Compatibility versions
  86. # template<typename T1>
  87. # void someInterface(T1 t1) { /* ... */ }
  88. # template<typename T1, typename T2>
  89. # void someInterface(T1 t1, T2 t2) { /* ... */ }
  90. # template<typename T1, typename T2, typename T3>
  91. # void someInterface(T1 t1, T2 t2, T3 t3) { /* ... */ }
  92. # #endif
  93. #
  94. # Symbol Macros
  95. # =============
  96. #
  97. # Some additional symbol-defines are created for particular features for
  98. # use as symbols which may be conditionally defined empty:
  99. #
  100. # .. code-block:: c++
  101. #
  102. # class MyClass ClimbingStats_DECL_CXX_FINAL
  103. # {
  104. # ClimbingStats_DECL_CXX_CONSTEXPR int someInterface() { return 42; }
  105. # };
  106. #
  107. # The ``ClimbingStats_DECL_CXX_FINAL`` macro will expand to ``final`` if the
  108. # compiler (and its flags) support the ``cxx_final`` feature, and the
  109. # ``ClimbingStats_DECL_CXX_CONSTEXPR`` macro will expand to ``constexpr``
  110. # if ``cxx_constexpr`` is supported.
  111. #
  112. # The following features generate corresponding symbol defines:
  113. #
  114. # ========================== =================================== =================
  115. # Feature Define Symbol
  116. # ========================== =================================== =================
  117. # ``c_restrict`` ``<PREFIX>_RESTRICT`` ``restrict``
  118. # ``cxx_constexpr`` ``<PREFIX>_CONSTEXPR`` ``constexpr``
  119. # ``cxx_deleted_functions`` ``<PREFIX>_DELETED_FUNCTION`` ``= delete``
  120. # ``cxx_extern_templates`` ``<PREFIX>_EXTERN_TEMPLATE`` ``extern``
  121. # ``cxx_final`` ``<PREFIX>_FINAL`` ``final``
  122. # ``cxx_noexcept`` ``<PREFIX>_NOEXCEPT`` ``noexcept``
  123. # ``cxx_noexcept`` ``<PREFIX>_NOEXCEPT_EXPR(X)`` ``noexcept(X)``
  124. # ``cxx_override`` ``<PREFIX>_OVERRIDE`` ``override``
  125. # ========================== =================================== =================
  126. #
  127. # Compatibility Implementation Macros
  128. # ===================================
  129. #
  130. # Some features are suitable for wrapping in a macro with a backward
  131. # compatibility implementation if the compiler does not support the feature.
  132. #
  133. # When the ``cxx_static_assert`` feature is not provided by the compiler,
  134. # a compatibility implementation is available via the
  135. # ``<PREFIX>_STATIC_ASSERT(COND)`` and
  136. # ``<PREFIX>_STATIC_ASSERT_MSG(COND, MSG)`` function-like macros. The macros
  137. # expand to ``static_assert`` where that compiler feature is available, and
  138. # to a compatibility implementation otherwise. In the first form, the
  139. # condition is stringified in the message field of ``static_assert``. In
  140. # the second form, the message ``MSG`` is passed to the message field of
  141. # ``static_assert``, or ignored if using the backward compatibility
  142. # implementation.
  143. #
  144. # The ``cxx_attribute_deprecated`` feature provides a macro definition
  145. # ``<PREFIX>_DEPRECATED``, which expands to either the standard
  146. # ``[[deprecated]]`` attribute or a compiler-specific decorator such
  147. # as ``__attribute__((__deprecated__))`` used by GNU compilers.
  148. #
  149. # The ``cxx_alignas`` feature provides a macro definition
  150. # ``<PREFIX>_ALIGNAS`` which expands to either the standard ``alignas``
  151. # decorator or a compiler-specific decorator such as
  152. # ``__attribute__ ((__aligned__))`` used by GNU compilers.
  153. #
  154. # The ``cxx_alignof`` feature provides a macro definition
  155. # ``<PREFIX>_ALIGNOF`` which expands to either the standard ``alignof``
  156. # decorator or a compiler-specific decorator such as ``__alignof__``
  157. # used by GNU compilers.
  158. #
  159. # ============================= ================================ =====================
  160. # Feature Define Symbol
  161. # ============================= ================================ =====================
  162. # ``cxx_alignas`` ``<PREFIX>_ALIGNAS`` ``alignas``
  163. # ``cxx_alignof`` ``<PREFIX>_ALIGNOF`` ``alignof``
  164. # ``cxx_nullptr`` ``<PREFIX>_NULLPTR`` ``nullptr``
  165. # ``cxx_static_assert`` ``<PREFIX>_STATIC_ASSERT`` ``static_assert``
  166. # ``cxx_static_assert`` ``<PREFIX>_STATIC_ASSERT_MSG`` ``static_assert``
  167. # ``cxx_attribute_deprecated`` ``<PREFIX>_DEPRECATED`` ``[[deprecated]]``
  168. # ``cxx_attribute_deprecated`` ``<PREFIX>_DEPRECATED_MSG`` ``[[deprecated]]``
  169. # ============================= ================================ =====================
  170. #
  171. # A use-case which arises with such deprecation macros is the deprecation
  172. # of an entire library. In that case, all public API in the library may
  173. # be decorated with the ``<PREFIX>_DEPRECATED`` macro. This results in
  174. # very noisy build output when building the library itself, so the macro
  175. # may be may be defined to empty in that case when building the deprecated
  176. # library:
  177. #
  178. # .. code-block:: cmake
  179. #
  180. # add_library(compat_support ${srcs})
  181. # target_compile_definitions(compat_support
  182. # PRIVATE
  183. # CompatSupport_DEPRECATED=
  184. # )
  185. #=============================================================================
  186. # Copyright 2014 Stephen Kelly <[email protected]>
  187. #
  188. # Distributed under the OSI-approved BSD License (the "License");
  189. # see accompanying file Copyright.txt for details.
  190. #
  191. # This software is distributed WITHOUT ANY WARRANTY; without even the
  192. # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  193. # See the License for more information.
  194. #=============================================================================
  195. # (To distribute this file outside of CMake, substitute the full
  196. # License text for the above reference.)
  197. include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)
  198. include(${CMAKE_CURRENT_LIST_DIR}/CMakeCompilerIdDetection.cmake)
  199. function(_load_compiler_variables CompilerId lang)
  200. include("${CMAKE_ROOT}/Modules/Compiler/${CompilerId}-${lang}-FeatureTests.cmake" OPTIONAL)
  201. set(_cmake_oldestSupported_${CompilerId} ${_cmake_oldestSupported} PARENT_SCOPE)
  202. foreach(feature ${ARGN})
  203. set(_cmake_feature_test_${CompilerId}_${feature} ${_cmake_feature_test_${feature}} PARENT_SCOPE)
  204. endforeach()
  205. include("${CMAKE_ROOT}/Modules/Compiler/${CompilerId}-DetermineCompiler.cmake" OPTIONAL)
  206. set(_compiler_id_version_compute_${CompilerId} ${_compiler_id_version_compute} PARENT_SCOPE)
  207. endfunction()
  208. function(write_compiler_detection_header
  209. file_keyword file_arg
  210. prefix_keyword prefix_arg
  211. )
  212. if (NOT file_keyword STREQUAL FILE)
  213. message(FATAL_ERROR "write_compiler_detection_header: FILE parameter missing.")
  214. endif()
  215. if (NOT prefix_keyword STREQUAL PREFIX)
  216. message(FATAL_ERROR "write_compiler_detection_header: PREFIX parameter missing.")
  217. endif()
  218. set(options)
  219. set(oneValueArgs VERSION EPILOG PROLOG)
  220. set(multiValueArgs COMPILERS FEATURES)
  221. cmake_parse_arguments(_WCD "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  222. if (NOT _WCD_COMPILERS)
  223. message(FATAL_ERROR "Invalid arguments. write_compiler_detection_header requires at least one compiler.")
  224. endif()
  225. if (NOT _WCD_FEATURES)
  226. message(FATAL_ERROR "Invalid arguments. write_compiler_detection_header requires at least one feature.")
  227. endif()
  228. if(_WCD_UNPARSED_ARGUMENTS)
  229. message(FATAL_ERROR "Unparsed arguments: ${_WCD_UNPARSED_ARGUMENTS}")
  230. endif()
  231. if(NOT _WCD_VERSION)
  232. set(_WCD_VERSION ${CMAKE_MINIMUM_REQUIRED_VERSION})
  233. endif()
  234. set(_min_version 3.1.0) # Version which introduced this function
  235. if (_WCD_VERSION VERSION_LESS _min_version)
  236. set(err "VERSION compatibility for write_compiler_detection_header is set to ${_WCD_VERSION}, which is too low.")
  237. set(err "${err} It must be set to at least ${_min_version}. ")
  238. set(err "${err} Either set the VERSION parameter to the write_compiler_detection_header function, or update")
  239. set(err "${err} your minimum required CMake version with the cmake_minimum_required command.")
  240. message(FATAL_ERROR "${err}")
  241. endif()
  242. set(compilers
  243. GNU
  244. Clang
  245. )
  246. set(_hex_compilers ADSP Borland Embarcadero SunPro)
  247. foreach(_comp ${_WCD_COMPILERS})
  248. list(FIND compilers ${_comp} idx)
  249. if (idx EQUAL -1)
  250. message(FATAL_ERROR "Unsupported compiler ${_comp}.")
  251. endif()
  252. if (NOT _need_hex_conversion)
  253. list(FIND _hex_compilers ${_comp} idx)
  254. if (NOT idx EQUAL -1)
  255. set(_need_hex_conversion TRUE)
  256. endif()
  257. endif()
  258. endforeach()
  259. set(file_content "
  260. // This is a generated file. Do not edit!
  261. #ifndef ${prefix_arg}_COMPILER_DETECTION_H
  262. #define ${prefix_arg}_COMPILER_DETECTION_H
  263. ")
  264. if (_WCD_PROLOG)
  265. set(file_content "${file_content}\n${_WCD_PROLOG}\n")
  266. endif()
  267. if (_need_hex_conversion)
  268. set(file_content "${file_content}
  269. #define ${prefix_arg}_DEC(X) (X)
  270. #define ${prefix_arg}_HEX(X) ( \\
  271. ((X)>>28 & 0xF) * 10000000 + \\
  272. ((X)>>24 & 0xF) * 1000000 + \\
  273. ((X)>>20 & 0xF) * 100000 + \\
  274. ((X)>>16 & 0xF) * 10000 + \\
  275. ((X)>>12 & 0xF) * 1000 + \\
  276. ((X)>>8 & 0xF) * 100 + \\
  277. ((X)>>4 & 0xF) * 10 + \\
  278. ((X) & 0xF) \\
  279. )\n")
  280. endif()
  281. foreach(feature ${_WCD_FEATURES})
  282. if (feature MATCHES "^cxx_")
  283. list(APPEND _langs CXX)
  284. list(APPEND CXX_features ${feature})
  285. elseif (feature MATCHES "^c_")
  286. list(APPEND _langs C)
  287. list(APPEND C_features ${feature})
  288. else()
  289. message(FATAL_ERROR "Unsupported feature ${feature}.")
  290. endif()
  291. endforeach()
  292. list(REMOVE_DUPLICATES _langs)
  293. foreach(_lang ${_langs})
  294. get_property(known_features GLOBAL PROPERTY CMAKE_${_lang}_KNOWN_FEATURES)
  295. foreach(feature ${${_lang}_features})
  296. list(FIND known_features ${feature} idx)
  297. if (idx EQUAL -1)
  298. message(FATAL_ERROR "Unsupported feature ${feature}.")
  299. endif()
  300. endforeach()
  301. if(_lang STREQUAL CXX)
  302. set(file_content "${file_content}\n#ifdef __cplusplus\n")
  303. else()
  304. set(file_content "${file_content}\n#ifndef __cplusplus\n")
  305. endif()
  306. compiler_id_detection(ID_CONTENT ${_lang} PREFIX ${prefix_arg}_
  307. ID_DEFINE
  308. )
  309. set(file_content "${file_content}${ID_CONTENT}\n")
  310. set(pp_if "if")
  311. foreach(compiler ${_WCD_COMPILERS})
  312. _load_compiler_variables(${compiler} ${_lang} ${${_lang}_features})
  313. set(file_content "${file_content}\n# ${pp_if} ${prefix_arg}_COMPILER_IS_${compiler}\n")
  314. set(file_content "${file_content}
  315. # if !(${_cmake_oldestSupported_${compiler}})
  316. # error Unsupported compiler version
  317. # endif\n")
  318. set(PREFIX ${prefix_arg}_)
  319. if (_need_hex_conversion)
  320. set(MACRO_DEC ${prefix_arg}_DEC)
  321. set(MACRO_HEX ${prefix_arg}_HEX)
  322. else()
  323. set(MACRO_DEC)
  324. set(MACRO_HEX)
  325. endif()
  326. string(CONFIGURE "${_compiler_id_version_compute_${compiler}}" VERSION_BLOCK @ONLY)
  327. set(file_content "${file_content}${VERSION_BLOCK}\n")
  328. set(PREFIX)
  329. set(MACRO_DEC)
  330. set(MACRO_HEX)
  331. set(pp_if "elif")
  332. foreach(feature ${${_lang}_features})
  333. string(TOUPPER ${feature} feature_upper)
  334. set(feature_PP "COMPILER_${feature_upper}")
  335. set(_define_item "\n# define ${prefix_arg}_${feature_PP} 0\n")
  336. if (_cmake_feature_test_${compiler}_${feature} STREQUAL "1")
  337. set(_define_item "\n# define ${prefix_arg}_${feature_PP} 1\n")
  338. elseif (_cmake_feature_test_${compiler}_${feature})
  339. set(_define_item "\n# define ${prefix_arg}_${feature_PP} 0\n")
  340. set(_define_item "\n# if ${_cmake_feature_test_${compiler}_${feature}}\n# define ${prefix_arg}_${feature_PP} 1\n# else${_define_item}# endif\n")
  341. endif()
  342. set(file_content "${file_content}${_define_item}")
  343. endforeach()
  344. endforeach()
  345. if(pp_if STREQUAL "elif")
  346. set(file_content "${file_content}
  347. # else
  348. # error Unsupported compiler
  349. # endif\n")
  350. endif()
  351. foreach(feature ${${_lang}_features})
  352. string(TOUPPER ${feature} feature_upper)
  353. set(feature_PP "COMPILER_${feature_upper}")
  354. set(def_name ${prefix_arg}_${feature_PP})
  355. if (feature STREQUAL c_restrict)
  356. set(def_value "${prefix_arg}_RESTRICT")
  357. set(file_content "${file_content}
  358. # if ${def_name}
  359. # define ${def_value} restrict
  360. # else
  361. # define ${def_value}
  362. # endif
  363. \n")
  364. endif()
  365. if (feature STREQUAL cxx_constexpr)
  366. set(def_value "${prefix_arg}_DECL_${feature_upper}")
  367. set(file_content "${file_content}
  368. # if ${def_name}
  369. # define ${def_value} constexpr
  370. # else
  371. # define ${def_value}
  372. # endif
  373. \n")
  374. endif()
  375. if (feature STREQUAL cxx_final)
  376. set(def_value "${prefix_arg}_DECL_${feature_upper}")
  377. set(file_content "${file_content}
  378. # if ${def_name}
  379. # define ${def_value} final
  380. # else
  381. # define ${def_value}
  382. # endif
  383. \n")
  384. endif()
  385. if (feature STREQUAL cxx_override)
  386. set(def_value "${prefix_arg}_DECL_${feature_upper}")
  387. set(file_content "${file_content}
  388. # if ${def_name}
  389. # define ${def_value} override
  390. # else
  391. # define ${def_value}
  392. # endif
  393. \n")
  394. endif()
  395. if (feature STREQUAL cxx_static_assert)
  396. set(def_value "${prefix_arg}_STATIC_ASSERT(X)")
  397. set(def_value_msg "${prefix_arg}_STATIC_ASSERT_MSG(X, MSG)")
  398. set(static_assert_struct "template<bool> struct ${prefix_arg}StaticAssert;\ntemplate<> struct ${prefix_arg}StaticAssert<true>{};\n")
  399. set(def_standard "# define ${def_value} static_assert(X, #X)\n# define ${def_value_msg} static_assert(X, MSG)")
  400. set(def_alternative "${static_assert_struct}# define ${def_value} sizeof(${prefix_arg}StaticAssert<X>)\n# define ${def_value_msg} sizeof(${prefix_arg}StaticAssert<X>)")
  401. set(file_content "${file_content}# if ${def_name}\n${def_standard}\n# else\n${def_alternative}\n# endif\n\n")
  402. endif()
  403. if (feature STREQUAL cxx_alignas)
  404. set(def_value "${prefix_arg}_ALIGNAS(X)")
  405. set(file_content "${file_content}
  406. # if ${def_name}
  407. # define ${def_value} alignas(X)
  408. # elif ${prefix_arg}_COMPILER_IS_GNU
  409. # define ${def_value} __attribute__ ((__aligned__(X)))
  410. # else
  411. # define ${def_value}
  412. # endif
  413. \n")
  414. endif()
  415. if (feature STREQUAL cxx_alignof)
  416. set(def_value "${prefix_arg}_ALIGNOF(X)")
  417. set(file_content "${file_content}
  418. # if ${def_name}
  419. # define ${def_value} alignof(X)
  420. # elif ${prefix_arg}_COMPILER_IS_GNU
  421. # define ${def_value} __alignof__(X)
  422. # endif
  423. \n")
  424. endif()
  425. if (feature STREQUAL cxx_deleted_functions)
  426. set(def_value "${prefix_arg}_DELETED_FUNCTION")
  427. set(file_content "${file_content}
  428. # if ${def_name}
  429. # define ${def_value} = delete
  430. # else
  431. # define ${def_value}
  432. # endif
  433. \n")
  434. endif()
  435. if (feature STREQUAL cxx_extern_templates)
  436. set(def_value "${prefix_arg}_EXTERN_TEMPLATE")
  437. set(file_content "${file_content}
  438. # if ${def_name}
  439. # define ${def_value} extern
  440. # else
  441. # define ${def_value}
  442. # endif
  443. \n")
  444. endif()
  445. if (feature STREQUAL cxx_noexcept)
  446. set(def_value "${prefix_arg}_NOEXCEPT")
  447. set(file_content "${file_content}
  448. # if ${def_name}
  449. # define ${def_value} noexcept
  450. # define ${def_value}_EXPR(X) noexcept(X)
  451. # else
  452. # define ${def_value}
  453. # define ${def_value}_EXPR(X)
  454. # endif
  455. \n")
  456. endif()
  457. if (feature STREQUAL cxx_nullptr)
  458. set(def_value "${prefix_arg}_NULLPTR")
  459. set(file_content "${file_content}
  460. # if ${def_name}
  461. # define ${def_value} nullptr
  462. # else
  463. # define ${def_value} static_cast<void*>(0)
  464. # endif
  465. \n")
  466. endif()
  467. if (feature STREQUAL cxx_attribute_deprecated)
  468. set(def_name ${prefix_arg}_${feature_PP})
  469. set(def_value "${prefix_arg}_DEPRECATED")
  470. set(file_content "${file_content}
  471. # ifndef ${def_value}
  472. # if ${def_name}
  473. # define ${def_value} [[deprecated]]
  474. # define ${def_value}_MSG(MSG) [[deprecated(MSG)]]
  475. # elif defined(__GNUC__) || defined(__clang__)
  476. # define ${def_value} __attribute__((__deprecated__))
  477. # define ${def_value}_MSG(MSG) __attribute__((__deprecated__(MSG)))
  478. # elif defined(_MSC_VER)
  479. # define ${def_value} __declspec(deprecated)
  480. # define ${def_value}_MSG(MSG) __declspec(deprecated(MSG))
  481. # else
  482. # define ${def_value}
  483. # define ${def_value}_MSG(MSG)
  484. # endif
  485. # endif
  486. \n")
  487. endif()
  488. endforeach()
  489. set(file_content "${file_content}#endif\n")
  490. endforeach()
  491. if (_WCD_EPILOG)
  492. set(file_content "${file_content}\n${_WCD_EPILOG}\n")
  493. endif()
  494. set(file_content "${file_content}\n#endif")
  495. set(CMAKE_CONFIGURABLE_FILE_CONTENT ${file_content})
  496. configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
  497. "${file_arg}"
  498. @ONLY
  499. )
  500. endfunction()