1.. cmake-manual-description: CMake Compile Features Reference
2
3cmake-compile-features(7)
4*************************
5
6.. only:: html
7
8   .. contents::
9
10Introduction
11============
12
13Project source code may depend on, or be conditional on, the availability
14of certain features of the compiler.  There are three use-cases which arise:
15`Compile Feature Requirements`_, `Optional Compile Features`_
16and `Conditional Compilation Options`_.
17
18While features are typically specified in programming language standards,
19CMake provides a primary user interface based on granular handling of
20the features, not the language standard that introduced the feature.
21
22The :prop_gbl:`CMAKE_C_KNOWN_FEATURES`, :prop_gbl:`CMAKE_CUDA_KNOWN_FEATURES`,
23and :prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global properties contain all the
24features known to CMake, regardless of compiler support for the feature.
25The :variable:`CMAKE_C_COMPILE_FEATURES`, :variable:`CMAKE_CUDA_COMPILE_FEATURES`
26, and :variable:`CMAKE_CXX_COMPILE_FEATURES` variables contain all features
27CMake knows are known to the compiler, regardless of language standard
28or compile flags needed to use them.
29
30Features known to CMake are named mostly following the same convention
31as the Clang feature test macros.  There are some exceptions, such as
32CMake using ``cxx_final`` and ``cxx_override`` instead of the single
33``cxx_override_control`` used by Clang.
34
35Note that there are no separate compile features properties or variables for
36the ``OBJC`` or ``OBJCXX`` languages.  These are based off ``C`` or ``C++``
37respectively, so the properties and variables for their corresponding base
38language should be used instead.
39
40Compile Feature Requirements
41============================
42
43Compile feature requirements may be specified with the
44:command:`target_compile_features` command.  For example, if a target must
45be compiled with compiler support for the
46:prop_gbl:`cxx_constexpr <CMAKE_CXX_KNOWN_FEATURES>` feature:
47
48.. code-block:: cmake
49
50  add_library(mylib requires_constexpr.cpp)
51  target_compile_features(mylib PRIVATE cxx_constexpr)
52
53In processing the requirement for the ``cxx_constexpr`` feature,
54:manual:`cmake(1)` will ensure that the in-use C++ compiler is capable
55of the feature, and will add any necessary flags such as ``-std=gnu++11``
56to the compile lines of C++ files in the ``mylib`` target.  A
57``FATAL_ERROR`` is issued if the compiler is not capable of the
58feature.
59
60The exact compile flags and language standard are deliberately not part
61of the user interface for this use-case.  CMake will compute the
62appropriate compile flags to use by considering the features specified
63for each target.
64
65Such compile flags are added even if the compiler supports the
66particular feature without the flag. For example, the GNU compiler
67supports variadic templates (with a warning) even if ``-std=gnu++98`` is
68used.  CMake adds the ``-std=gnu++11`` flag if ``cxx_variadic_templates``
69is specified as a requirement.
70
71In the above example, ``mylib`` requires ``cxx_constexpr`` when it
72is built itself, but consumers of ``mylib`` are not required to use a
73compiler which supports ``cxx_constexpr``.  If the interface of
74``mylib`` does require the ``cxx_constexpr`` feature (or any other
75known feature), that may be specified with the ``PUBLIC`` or
76``INTERFACE`` signatures of :command:`target_compile_features`:
77
78.. code-block:: cmake
79
80  add_library(mylib requires_constexpr.cpp)
81  # cxx_constexpr is a usage-requirement
82  target_compile_features(mylib PUBLIC cxx_constexpr)
83
84  # main.cpp will be compiled with -std=gnu++11 on GNU for cxx_constexpr.
85  add_executable(myexe main.cpp)
86  target_link_libraries(myexe mylib)
87
88Feature requirements are evaluated transitively by consuming the link
89implementation.  See :manual:`cmake-buildsystem(7)` for more on
90transitive behavior of build properties and usage requirements.
91
92.. _`Requiring Language Standards`:
93
94Requiring Language Standards
95----------------------------
96
97In projects that use a large number of commonly available features from
98a particular language standard (e.g. C++ 11) one may specify a
99meta-feature (e.g. ``cxx_std_11``) that requires use of a compiler mode
100that is at minimum aware of that standard, but could be greater.
101This is simpler than specifying all the features individually, but does
102not guarantee the existence of any particular feature.
103Diagnosis of use of unsupported features will be delayed until compile time.
104
105For example, if C++ 11 features are used extensively in a project's
106header files, then clients must use a compiler mode that is no less
107than C++ 11.  This can be requested with the code:
108
109.. code-block:: cmake
110
111  target_compile_features(mylib PUBLIC cxx_std_11)
112
113In this example, CMake will ensure the compiler is invoked in a mode
114of at-least C++ 11 (or C++ 14, C++ 17, ...), adding flags such as
115``-std=gnu++11`` if necessary.  This applies to sources within ``mylib``
116as well as any dependents (that may include headers from ``mylib``).
117
118Availability of Compiler Extensions
119-----------------------------------
120
121The :prop_tgt:`<LANG>_EXTENSIONS` target property defaults to the compiler's
122default (see :variable:`CMAKE_<LANG>_EXTENSIONS_DEFAULT`). Note that because
123most compilers enable extensions by default, this may expose portability bugs
124in user code or in the headers of third-party dependencies.
125
126:prop_tgt:`<LANG>_EXTENSIONS` used to default to ``ON``. See :policy:`CMP0128`.
127
128Optional Compile Features
129=========================
130
131Compile features may be preferred if available, without creating a hard
132requirement.   This can be achieved by *not* specifying features with
133:command:`target_compile_features` and instead checking the compiler
134capabilities with preprocessor conditions in project code.
135
136In this use-case, the project may wish to establish a particular language
137standard if available from the compiler, and use preprocessor conditions
138to detect the features actually available.  A language standard may be
139established by `Requiring Language Standards`_ using
140:command:`target_compile_features` with meta-features like ``cxx_std_11``,
141or by setting the :prop_tgt:`CXX_STANDARD` target property or
142:variable:`CMAKE_CXX_STANDARD` variable.
143
144See also policy :policy:`CMP0120` and legacy documentation on
145:ref:`Example Usage <WCDH Example Usage>` of the deprecated
146:module:`WriteCompilerDetectionHeader` module.
147
148Conditional Compilation Options
149===============================
150
151Libraries may provide entirely different header files depending on
152requested compiler features.
153
154For example, a header at ``with_variadics/interface.h`` may contain:
155
156.. code-block:: c++
157
158  template<int I, int... Is>
159  struct Interface;
160
161  template<int I>
162  struct Interface<I>
163  {
164    static int accumulate()
165    {
166      return I;
167    }
168  };
169
170  template<int I, int... Is>
171  struct Interface
172  {
173    static int accumulate()
174    {
175      return I + Interface<Is...>::accumulate();
176    }
177  };
178
179while a header at ``no_variadics/interface.h`` may contain:
180
181.. code-block:: c++
182
183  template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
184  struct Interface
185  {
186    static int accumulate() { return I1 + I2 + I3 + I4; }
187  };
188
189It may be possible to write an abstraction ``interface.h`` header
190containing something like:
191
192.. code-block:: c++
193
194  #ifdef HAVE_CXX_VARIADIC_TEMPLATES
195  #include "with_variadics/interface.h"
196  #else
197  #include "no_variadics/interface.h"
198  #endif
199
200However this could be unmaintainable if there are many files to
201abstract. What is needed is to use alternative include directories
202depending on the compiler capabilities.
203
204CMake provides a ``COMPILE_FEATURES``
205:manual:`generator expression <cmake-generator-expressions(7)>` to implement
206such conditions.  This may be used with the build-property commands such as
207:command:`target_include_directories` and :command:`target_link_libraries`
208to set the appropriate :manual:`buildsystem <cmake-buildsystem(7)>`
209properties:
210
211.. code-block:: cmake
212
213  add_library(foo INTERFACE)
214  set(with_variadics ${CMAKE_CURRENT_SOURCE_DIR}/with_variadics)
215  set(no_variadics ${CMAKE_CURRENT_SOURCE_DIR}/no_variadics)
216  target_include_directories(foo
217    INTERFACE
218      "$<$<COMPILE_FEATURES:cxx_variadic_templates>:${with_variadics}>"
219      "$<$<NOT:$<COMPILE_FEATURES:cxx_variadic_templates>>:${no_variadics}>"
220    )
221
222Consuming code then simply links to the ``foo`` target as usual and uses
223the feature-appropriate include directory
224
225.. code-block:: cmake
226
227  add_executable(consumer_with consumer_with.cpp)
228  target_link_libraries(consumer_with foo)
229  set_property(TARGET consumer_with CXX_STANDARD 11)
230
231  add_executable(consumer_no consumer_no.cpp)
232  target_link_libraries(consumer_no foo)
233
234Supported Compilers
235===================
236
237CMake is currently aware of the :prop_tgt:`C++ standards <CXX_STANDARD>`
238and :prop_gbl:`compile features <CMAKE_CXX_KNOWN_FEATURES>` available from
239the following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
240versions specified for each:
241
242* ``AppleClang``: Apple Clang for Xcode versions 4.4+.
243* ``Clang``: Clang compiler versions 2.9+.
244* ``GNU``: GNU compiler versions 4.4+.
245* ``MSVC``: Microsoft Visual Studio versions 2010+.
246* ``SunPro``: Oracle SolarisStudio versions 12.4+.
247* ``Intel``: Intel compiler versions 12.1+.
248
249CMake is currently aware of the :prop_tgt:`C standards <C_STANDARD>`
250and :prop_gbl:`compile features <CMAKE_C_KNOWN_FEATURES>` available from
251the following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
252versions specified for each:
253
254* all compilers and versions listed above for C++.
255* ``GNU``: GNU compiler versions 3.4+
256
257CMake is currently aware of the :prop_tgt:`C++ standards <CXX_STANDARD>` and
258their associated meta-features (e.g. ``cxx_std_11``) available from the
259following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
260versions specified for each:
261
262* ``Cray``: Cray Compiler Environment version 8.1+.
263* ``Fujitsu``: Fujitsu HPC compiler 4.0+.
264* ``PGI``: PGI version 12.10+.
265* ``NVHPC``: NVIDIA HPC compilers version 11.0+.
266* ``TI``: Texas Instruments compiler.
267* ``XL``: IBM XL version 10.1+.
268
269CMake is currently aware of the :prop_tgt:`C standards <C_STANDARD>` and
270their associated meta-features (e.g. ``c_std_99``) available from the
271following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
272versions specified for each:
273
274* all compilers and versions listed above with only meta-features for C++.
275
276CMake is currently aware of the :prop_tgt:`CUDA standards <CUDA_STANDARD>` and
277their associated meta-features (e.g. ``cuda_std_11``) available from the
278following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
279versions specified for each:
280
281* ``Clang``: Clang compiler 5.0+.
282* ``NVIDIA``: NVIDIA nvcc compiler 7.5+.
283