1 .. cmake-manual-description: CMake Compile Features Reference
3 cmake-compile-features(7)
4 *************************
13 Project source code may depend on, or be conditional on, the availability
14 of certain features of the compiler. There are three use-cases which arise:
15 `Compile Feature Requirements`_, `Optional Compile Features`_
16 and `Conditional Compilation Options`_.
18 While features are typically specified in programming language standards,
19 CMake provides a primary user interface based on granular handling of
20 the features, not the language standard that introduced the feature.
22 The :prop_gbl:`CMAKE_C_KNOWN_FEATURES`, :prop_gbl:`CMAKE_CUDA_KNOWN_FEATURES`,
23 and :prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global properties contain all the
24 features known to CMake, regardless of compiler support for the feature.
25 The :variable:`CMAKE_C_COMPILE_FEATURES`, :variable:`CMAKE_CUDA_COMPILE_FEATURES`
26 , and :variable:`CMAKE_CXX_COMPILE_FEATURES` variables contain all features
27 CMake knows are known to the compiler, regardless of language standard
28 or compile flags needed to use them.
30 Features known to CMake are named mostly following the same convention
31 as the Clang feature test macros. There are some exceptions, such as
32 CMake using ``cxx_final`` and ``cxx_override`` instead of the single
33 ``cxx_override_control`` used by Clang.
35 Note that there are no separate compile features properties or variables for
36 the ``OBJC`` or ``OBJCXX`` languages. These are based off ``C`` or ``C++``
37 respectively, so the properties and variables for their corresponding base
38 language should be used instead.
40 Compile Feature Requirements
41 ============================
43 Compile feature requirements may be specified with the
44 :command:`target_compile_features` command. For example, if a target must
45 be compiled with compiler support for the
46 :prop_gbl:`cxx_constexpr <CMAKE_CXX_KNOWN_FEATURES>` feature:
50 add_library(mylib requires_constexpr.cpp)
51 target_compile_features(mylib PRIVATE cxx_constexpr)
53 In processing the requirement for the ``cxx_constexpr`` feature,
54 :manual:`cmake(1)` will ensure that the in-use C++ compiler is capable
55 of the feature, and will add any necessary flags such as ``-std=gnu++11``
56 to the compile lines of C++ files in the ``mylib`` target. A
57 ``FATAL_ERROR`` is issued if the compiler is not capable of the
60 The exact compile flags and language standard are deliberately not part
61 of the user interface for this use-case. CMake will compute the
62 appropriate compile flags to use by considering the features specified
65 Such compile flags are added even if the compiler supports the
66 particular feature without the flag. For example, the GNU compiler
67 supports variadic templates (with a warning) even if ``-std=gnu++98`` is
68 used. CMake adds the ``-std=gnu++11`` flag if ``cxx_variadic_templates``
69 is specified as a requirement.
71 In the above example, ``mylib`` requires ``cxx_constexpr`` when it
72 is built itself, but consumers of ``mylib`` are not required to use a
73 compiler which supports ``cxx_constexpr``. If the interface of
74 ``mylib`` does require the ``cxx_constexpr`` feature (or any other
75 known feature), that may be specified with the ``PUBLIC`` or
76 ``INTERFACE`` signatures of :command:`target_compile_features`:
80 add_library(mylib requires_constexpr.cpp)
81 # cxx_constexpr is a usage-requirement
82 target_compile_features(mylib PUBLIC cxx_constexpr)
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)
88 Feature requirements are evaluated transitively by consuming the link
89 implementation. See :manual:`cmake-buildsystem(7)` for more on
90 transitive behavior of build properties and usage requirements.
92 .. _`Requiring Language Standards`:
94 Requiring Language Standards
95 ----------------------------
97 In projects that use a large number of commonly available features from
98 a particular language standard (e.g. C++ 11) one may specify a
99 meta-feature (e.g. ``cxx_std_11``) that requires use of a compiler mode
100 that is at minimum aware of that standard, but could be greater.
101 This is simpler than specifying all the features individually, but does
102 not guarantee the existence of any particular feature.
103 Diagnosis of use of unsupported features will be delayed until compile time.
105 For example, if C++ 11 features are used extensively in a project's
106 header files, then clients must use a compiler mode that is no less
107 than C++ 11. This can be requested with the code:
109 .. code-block:: cmake
111 target_compile_features(mylib PUBLIC cxx_std_11)
113 In this example, CMake will ensure the compiler is invoked in a mode
114 of 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``
116 as well as any dependents (that may include headers from ``mylib``).
118 Availability of Compiler Extensions
119 -----------------------------------
121 Because the :prop_tgt:`CXX_EXTENSIONS` target property is ``ON`` by default,
122 CMake uses extended variants of language dialects by default, such as
123 ``-std=gnu++11`` instead of ``-std=c++11``. That target property may be
124 set to ``OFF`` to use the non-extended variant of the dialect flag. Note
125 that because most compilers enable extensions by default, this could
126 expose cross-platform bugs in user code or in the headers of third-party
129 Optional Compile Features
130 =========================
132 Compile features may be preferred if available, without creating a hard
133 requirement. For example, a library may provides alternative
134 implementations depending on whether the ``cxx_variadic_templates``
135 feature is available:
139 #if Foo_COMPILER_CXX_VARIADIC_TEMPLATES
140 template<int I, int... Is>
146 static int accumulate()
152 template<int I, int... Is>
155 static int accumulate()
157 return I + Interface<Is...>::accumulate();
161 template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
164 static int accumulate() { return I1 + I2 + I3 + I4; }
168 Such an interface depends on using the correct preprocessor defines for the
169 compiler features. CMake can generate a header file containing such
170 defines using the :module:`WriteCompilerDetectionHeader` module. The
171 module contains the ``write_compiler_detection_header`` function which
172 accepts parameters to control the content of the generated header file:
174 .. code-block:: cmake
176 write_compiler_detection_header(
177 FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
181 cxx_variadic_templates
184 Such a header file may be used internally in the source code of a project,
185 and it may be installed and used in the interface of library code.
187 For each feature listed in ``FEATURES``, a preprocessor definition
188 is created in the header file, and defined to either ``1`` or ``0``.
190 Additionally, some features call for additional defines, such as the
191 ``cxx_final`` and ``cxx_override`` features. Rather than being used in
192 ``#ifdef`` code, the ``final`` keyword is abstracted by a symbol
193 which is defined to either ``final``, a compiler-specific equivalent, or
194 to empty. That way, C++ code can be written to unconditionally use the
195 symbol, and compiler support determines what it is expanded to:
200 virtual void Execute() = 0;
203 struct Concrete Foo_FINAL {
204 void Execute() Foo_OVERRIDE;
207 In this case, ``Foo_FINAL`` will expand to ``final`` if the
208 compiler supports the keyword, or to empty otherwise.
210 In this use-case, the CMake code will wish to enable a particular language
211 standard if available from the compiler. The :prop_tgt:`CXX_STANDARD`
212 target property variable may be set to the desired language standard
213 for a particular target, and the :variable:`CMAKE_CXX_STANDARD` may be
214 set to influence all following targets:
216 .. code-block:: cmake
218 write_compiler_detection_header(
219 FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
223 cxx_final cxx_override
226 # Includes foo_compiler_detection.h and uses the Foo_FINAL symbol
227 # which will expand to 'final' if the compiler supports the requested
229 add_library(foo foo.cpp)
230 set_property(TARGET foo PROPERTY CXX_STANDARD 11)
232 # Includes foo_compiler_detection.h and uses the Foo_FINAL symbol
233 # which will expand to 'final' if the compiler supports the feature,
234 # even though CXX_STANDARD is not set explicitly. The requirement of
235 # cxx_constexpr causes CMake to set CXX_STANDARD internally, which
236 # affects the compile flags.
237 add_library(foo_impl foo_impl.cpp)
238 target_compile_features(foo_impl PRIVATE cxx_constexpr)
240 The ``write_compiler_detection_header`` function also creates compatibility
241 code for other features which have standard equivalents. For example, the
242 ``cxx_static_assert`` feature is emulated with a template and abstracted
243 via the ``<PREFIX>_STATIC_ASSERT`` and ``<PREFIX>_STATIC_ASSERT_MSG``
246 Conditional Compilation Options
247 ===============================
249 Libraries may provide entirely different header files depending on
250 requested compiler features.
252 For example, a header at ``with_variadics/interface.h`` may contain:
256 template<int I, int... Is>
262 static int accumulate()
268 template<int I, int... Is>
271 static int accumulate()
273 return I + Interface<Is...>::accumulate();
277 while a header at ``no_variadics/interface.h`` may contain:
281 template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
284 static int accumulate() { return I1 + I2 + I3 + I4; }
287 It would be possible to write a abstraction ``interface.h`` header
288 containing something like:
292 #include "foo_compiler_detection.h"
293 #if Foo_COMPILER_CXX_VARIADIC_TEMPLATES
294 #include "with_variadics/interface.h"
296 #include "no_variadics/interface.h"
299 However this could be unmaintainable if there are many files to
300 abstract. What is needed is to use alternative include directories
301 depending on the compiler capabilities.
303 CMake provides a ``COMPILE_FEATURES``
304 :manual:`generator expression <cmake-generator-expressions(7)>` to implement
305 such conditions. This may be used with the build-property commands such as
306 :command:`target_include_directories` and :command:`target_link_libraries`
307 to set the appropriate :manual:`buildsystem <cmake-buildsystem(7)>`
310 .. code-block:: cmake
312 add_library(foo INTERFACE)
313 set(with_variadics ${CMAKE_CURRENT_SOURCE_DIR}/with_variadics)
314 set(no_variadics ${CMAKE_CURRENT_SOURCE_DIR}/no_variadics)
315 target_include_directories(foo
317 "$<$<COMPILE_FEATURES:cxx_variadic_templates>:${with_variadics}>"
318 "$<$<NOT:$<COMPILE_FEATURES:cxx_variadic_templates>>:${no_variadics}>"
321 Consuming code then simply links to the ``foo`` target as usual and uses
322 the feature-appropriate include directory
324 .. code-block:: cmake
326 add_executable(consumer_with consumer_with.cpp)
327 target_link_libraries(consumer_with foo)
328 set_property(TARGET consumer_with CXX_STANDARD 11)
330 add_executable(consumer_no consumer_no.cpp)
331 target_link_libraries(consumer_no foo)
336 CMake is currently aware of the :prop_tgt:`C++ standards <CXX_STANDARD>`
337 and :prop_gbl:`compile features <CMAKE_CXX_KNOWN_FEATURES>` available from
338 the following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
339 versions specified for each:
341 * ``AppleClang``: Apple Clang for Xcode versions 4.4+.
342 * ``Clang``: Clang compiler versions 2.9+.
343 * ``GNU``: GNU compiler versions 4.4+.
344 * ``MSVC``: Microsoft Visual Studio versions 2010+.
345 * ``SunPro``: Oracle SolarisStudio versions 12.4+.
346 * ``Intel``: Intel compiler versions 12.1+.
348 CMake is currently aware of the :prop_tgt:`C standards <C_STANDARD>`
349 and :prop_gbl:`compile features <CMAKE_C_KNOWN_FEATURES>` available from
350 the following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
351 versions specified for each:
353 * all compilers and versions listed above for C++.
354 * ``GNU``: GNU compiler versions 3.4+
356 CMake is currently aware of the :prop_tgt:`C++ standards <CXX_STANDARD>` and
357 their associated meta-features (e.g. ``cxx_std_11``) available from the
358 following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
359 versions specified for each:
361 * ``Cray``: Cray Compiler Environment version 8.1+.
362 * ``PGI``: PGI version 12.10+.
363 * ``NVHPC``: NVIDIA HPC compilers version 11.0+.
364 * ``TI``: Texas Instruments compiler.
365 * ``XL``: IBM XL version 10.1+.
367 CMake is currently aware of the :prop_tgt:`C standards <C_STANDARD>` and
368 their associated meta-features (e.g. ``c_std_99``) available from the
369 following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
370 versions specified for each:
372 * all compilers and versions listed above with only meta-features for C++.
374 CMake is currently aware of the :prop_tgt:`CUDA standards <CUDA_STANDARD>` and
375 their associated meta-features (e.g. ``cuda_std_11``) available from the
376 following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
377 versions specified for each:
379 * ``Clang``: Clang compiler 5.0+.
380 * ``NVIDIA``: NVIDIA nvcc compiler 7.5+.