cmake-compile-features.7.rst 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. .. cmake-manual-description: CMake Compile Features Reference
  2. cmake-compile-features(7)
  3. *************************
  4. .. only:: html
  5. .. contents::
  6. Introduction
  7. ============
  8. Project source code may depend on, or be conditional on, the availability
  9. of certain features of the compiler. There are three use-cases which arise:
  10. `Compile Feature Requirements`_, `Optional Compile Features`_
  11. and `Conditional Compilation Options`_.
  12. While features are typically specified in programming language standards,
  13. CMake provides a primary user interface based on granular handling of
  14. the features, not the language standard that introduced the feature.
  15. The :prop_gbl:`CMAKE_C_KNOWN_FEATURES` and
  16. :prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global properties contain all the
  17. features known to CMake, regardless of compiler support for the feature.
  18. The :variable:`CMAKE_C_COMPILE_FEATURES` and
  19. :variable:`CMAKE_CXX_COMPILE_FEATURES` variables contain all features
  20. CMake knows are known to the compiler, regardless of language standard
  21. or compile flags needed to use them.
  22. Features known to CMake are named mostly following the same convention
  23. as the Clang feature test macros. The are some exceptions, such as
  24. CMake using ``cxx_final`` and ``cxx_override`` instead of the single
  25. ``cxx_override_control`` used by Clang.
  26. Compile Feature Requirements
  27. ============================
  28. Compile feature requirements may be specified with the
  29. :command:`target_compile_features` command. For example, if a target must
  30. be compiled with compiler support for the
  31. :prop_gbl:`cxx_constexpr <CMAKE_CXX_KNOWN_FEATURES>` feature:
  32. .. code-block:: cmake
  33. add_library(mylib requires_constexpr.cpp)
  34. target_compile_features(mylib PRIVATE cxx_constexpr)
  35. In processing the requirement for the ``cxx_constexpr`` feature,
  36. :manual:`cmake(1)` will ensure that the in-use C++ compiler is capable
  37. of the feature, and will add any necessary flags such as ``-std=gnu++11``
  38. to the compile lines of C++ files in the ``mylib`` target. A
  39. ``FATAL_ERROR`` is issued if the compiler is not capable of the
  40. feature.
  41. The exact compile flags and language standard are deliberately not part
  42. of the user interface for this use-case. CMake will compute the
  43. appropriate compile flags to use by considering the features specified
  44. for each target.
  45. Such compile flags are added even if the compiler supports the
  46. particular feature without the flag. For example, the GNU compiler
  47. supports variadic templates (with a warning) even if ``-std=gnu++98`` is
  48. used. CMake adds the ``-std=gnu++11`` flag if ``cxx_variadic_templates``
  49. is specified as a requirement.
  50. In the above example, ``mylib`` requires ``cxx_constexpr`` when it
  51. is built itself, but consumers of ``mylib`` are not required to use a
  52. compiler which supports ``cxx_constexpr``. If the interface of
  53. ``mylib`` does require the ``cxx_constexpr`` feature (or any other
  54. known feature), that may be specified with the ``PUBLIC`` or
  55. ``INTERFACE`` signatures of :command:`target_compile_features`:
  56. .. code-block:: cmake
  57. add_library(mylib requires_constexpr.cpp)
  58. # cxx_constexpr is a usage-requirement
  59. target_compile_features(mylib PUBLIC cxx_constexpr)
  60. # main.cpp will be compiled with -std=gnu++11 on GNU for cxx_constexpr.
  61. add_executable(myexe main.cpp)
  62. target_link_libraries(myexe mylib)
  63. Feature requirements are evaluated transitively by consuming the link
  64. implementation. See :manual:`cmake-buildsystem(7)` for more on
  65. transitive behavior of build properties and usage requirements.
  66. Because the :prop_tgt:`CXX_EXTENSIONS` target property is ``ON`` by default,
  67. CMake uses extended variants of language dialects by default, such as
  68. ``-std=gnu++11`` instead of ``-std=c++11``. That target property may be
  69. set to ``OFF`` to use the non-extended variant of the dialect flag. Note
  70. that because most compilers enable extensions by default, this could
  71. expose cross-platform bugs in user code or in the headers of third-party
  72. dependencies.
  73. Optional Compile Features
  74. =========================
  75. Compile features may be preferred if available, without creating a hard
  76. requirement. For example, a library may provides alternative
  77. implementations depending on whether the ``cxx_variadic_templates``
  78. feature is available:
  79. .. code-block:: c++
  80. #if Foo_COMPILER_CXX_VARIADIC_TEMPLATES
  81. template<int I, int... Is>
  82. struct Interface;
  83. template<int I>
  84. struct Interface<I>
  85. {
  86. static int accumulate()
  87. {
  88. return I;
  89. }
  90. };
  91. template<int I, int... Is>
  92. struct Interface
  93. {
  94. static int accumulate()
  95. {
  96. return I + Interface<Is...>::accumulate();
  97. }
  98. };
  99. #else
  100. template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
  101. struct Interface
  102. {
  103. static int accumulate() { return I1 + I2 + I3 + I4; }
  104. };
  105. #endif
  106. Such an interface depends on using the correct preprocessor defines for the
  107. compiler features. CMake can generate a header file containing such
  108. defines using the :module:`WriteCompilerDetectionHeader` module. The
  109. module contains the ``write_compiler_detection_header`` function which
  110. accepts parameters to control the content of the generated header file:
  111. .. code-block:: cmake
  112. write_compiler_detection_header(
  113. FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
  114. PREFIX Foo
  115. COMPILERS GNU
  116. FEATURES
  117. cxx_variadic_templates
  118. )
  119. Such a header file may be used internally in the source code of a project,
  120. and it may be installed and used in the interface of library code.
  121. For each feature listed in ``FEATURES``, a preprocessor definition
  122. is created in the header file, and defined to either ``1`` or ``0``.
  123. Additionally, some features call for additional defines, such as the
  124. ``cxx_final`` and ``cxx_override`` features. Rather than being used in
  125. ``#ifdef`` code, the ``final`` keyword is abstracted by a symbol
  126. which is defined to either ``final``, a compiler-specific equivalent, or
  127. to empty. That way, C++ code can be written to unconditionally use the
  128. symbol, and compiler support determines what it is expanded to:
  129. .. code-block:: c++
  130. struct Interface {
  131. virtual void Execute() = 0;
  132. };
  133. struct Concrete Foo_FINAL {
  134. void Execute() Foo_OVERRIDE;
  135. };
  136. In this case, ``Foo_FINAL`` will expand to ``final`` if the
  137. compiler supports the keyword, or to empty otherwise.
  138. In this use-case, the CMake code will wish to enable a particular language
  139. standard if available from the compiler. The :prop_tgt:`CXX_STANDARD`
  140. target property variable may be set to the desired language standard
  141. for a particular target, and the :variable:`CMAKE_CXX_STANDARD` may be
  142. set to influence all following targets:
  143. .. code-block:: cmake
  144. write_compiler_detection_header(
  145. FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
  146. PREFIX Foo
  147. COMPILERS GNU
  148. FEATURES
  149. cxx_final cxx_override
  150. )
  151. # Includes foo_compiler_detection.h and uses the Foo_FINAL symbol
  152. # which will expand to 'final' if the compiler supports the requested
  153. # CXX_STANDARD.
  154. add_library(foo foo.cpp)
  155. set_property(TARGET foo PROPERTY CXX_STANDARD 11)
  156. # Includes foo_compiler_detection.h and uses the Foo_FINAL symbol
  157. # which will expand to 'final' if the compiler supports the feature,
  158. # even though CXX_STANDARD is not set explicitly. The requirement of
  159. # cxx_constexpr causes CMake to set CXX_STANDARD internally, which
  160. # affects the compile flags.
  161. add_library(foo_impl foo_impl.cpp)
  162. target_compile_features(foo_impl PRIVATE cxx_constexpr)
  163. The ``write_compiler_detection_header`` function also creates compatibility
  164. code for other features which have standard equivalents. For example, the
  165. ``cxx_static_assert`` feature is emulated with a template and abstracted
  166. via the ``<PREFIX>_STATIC_ASSERT`` and ``<PREFIX>_STATIC_ASSERT_MSG``
  167. function-macros.
  168. Conditional Compilation Options
  169. ===============================
  170. Libraries may provide entirely different header files depending on
  171. requested compiler features.
  172. For example, a header at ``with_variadics/interface.h`` may contain:
  173. .. code-block:: c++
  174. template<int I, int... Is>
  175. struct Interface;
  176. template<int I>
  177. struct Interface<I>
  178. {
  179. static int accumulate()
  180. {
  181. return I;
  182. }
  183. };
  184. template<int I, int... Is>
  185. struct Interface
  186. {
  187. static int accumulate()
  188. {
  189. return I + Interface<Is...>::accumulate();
  190. }
  191. };
  192. while a header at ``no_variadics/interface.h`` may contain:
  193. .. code-block:: c++
  194. template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
  195. struct Interface
  196. {
  197. static int accumulate() { return I1 + I2 + I3 + I4; }
  198. };
  199. It would be possible to write a abstraction ``interface.h`` header
  200. containing something like:
  201. .. code-block:: c++
  202. #include "foo_compiler_detection.h"
  203. #if Foo_COMPILER_CXX_VARIADIC_TEMPLATES
  204. #include "with_variadics/interface.h"
  205. #else
  206. #include "no_variadics/interface.h"
  207. #endif
  208. However this could be unmaintainable if there are many files to
  209. abstract. What is needed is to use alternative include directories
  210. depending on the compiler capabilities.
  211. CMake provides a ``COMPILE_FEATURES``
  212. :manual:`generator expression <cmake-generator-expressions(7)>` to implement
  213. such conditions. This may be used with the build-property commands such as
  214. :command:`target_include_directories` and :command:`target_link_libraries`
  215. to set the appropriate :manual:`buildsystem <cmake-buildsystem(7)>`
  216. properties:
  217. .. code-block:: cmake
  218. add_library(foo INTERFACE)
  219. set(with_variadics ${CMAKE_CURRENT_SOURCE_DIR}/with_variadics)
  220. set(no_variadics ${CMAKE_CURRENT_SOURCE_DIR}/no_variadics)
  221. target_include_directories(foo
  222. INTERFACE
  223. "$<$<COMPILE_FEATURES:cxx_variadic_templates>:${with_variadics}>"
  224. "$<$<NOT:$<COMPILE_FEATURES:cxx_variadic_templates>>:${no_variadics}>"
  225. )
  226. Consuming code then simply links to the ``foo`` target as usual and uses
  227. the feature-appropriate include directory
  228. .. code-block:: cmake
  229. add_executable(consumer_with consumer_with.cpp)
  230. target_link_libraries(consumer_with foo)
  231. set_property(TARGET consumer_with CXX_STANDARD 11)
  232. add_executable(consumer_no consumer_no.cpp)
  233. target_link_libraries(consumer_no foo)
  234. Supported Compilers
  235. ===================
  236. CMake is currently aware of the :prop_tgt:`language standards <CXX_STANDARD>`
  237. and :prop_gbl:`compile features <CMAKE_CXX_KNOWN_FEATURES>` available from
  238. the following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
  239. versions specified for each:
  240. * ``AppleClang``: Apple Clang for Xcode versions 4.4 though 6.2.
  241. * ``Clang``: Clang compiler versions 2.9 through 3.4.
  242. * ``GNU``: GNU compiler versions 4.4 through 5.0.
  243. * ``MSVC``: Microsoft Visual Studio versions 2010 through 2015.
  244. * ``SunPro``: Oracle SolarisStudio version 12.4.
  245. * ``Intel``: Intel compiler versions 12.1 through 16.0 on UNIX platforms.