1CMAKE-COMPILE-FEATURES(7) CMake CMAKE-COMPILE-FEATURES(7)
2
3
4
6 cmake-compile-features - CMake Compile Features Reference
7
9 Project source code may depend on, or be conditional on, the availabil‐
10 ity of certain features of the compiler. There are three use-cases
11 which arise: Compile Feature Requirements, Optional Compile Features
12 and Conditional Compilation Options.
13
14 While features are typically specified in programming language stan‐
15 dards, CMake provides a primary user interface based on granular han‐
16 dling of the features, not the language standard that introduced the
17 feature.
18
19 The CMAKE_C_KNOWN_FEATURES, CMAKE_CUDA_KNOWN_FEATURES, and
20 CMAKE_CXX_KNOWN_FEATURES global properties contain all the features
21 known to CMake, regardless of compiler support for the feature. The
22 CMAKE_C_COMPILE_FEATURES, CMAKE_CUDA_COMPILE_FEATURES , and
23 CMAKE_CXX_COMPILE_FEATURES variables contain all features CMake knows
24 are known to the compiler, regardless of language standard or compile
25 flags needed to use them.
26
27 Features known to CMake are named mostly following the same convention
28 as the Clang feature test macros. There are some exceptions, such as
29 CMake using cxx_final and cxx_override instead of the single cxx_over‐
30 ride_control used by Clang.
31
32 Note that there are no separate compile features properties or vari‐
33 ables for the OBJC or OBJCXX languages. These are based off C or C++
34 respectively, so the properties and variables for their corresponding
35 base language should be used instead.
36
38 Compile feature requirements may be specified with the target_com‐
39 pile_features() command. For example, if a target must be compiled
40 with compiler support for the cxx_constexpr feature:
41
42 add_library(mylib requires_constexpr.cpp)
43 target_compile_features(mylib PRIVATE cxx_constexpr)
44
45 In processing the requirement for the cxx_constexpr feature, cmake(1)
46 will ensure that the in-use C++ compiler is capable of the feature, and
47 will add any necessary flags such as -std=gnu++11 to the compile lines
48 of C++ files in the mylib target. A FATAL_ERROR is issued if the com‐
49 piler is not capable of the feature.
50
51 The exact compile flags and language standard are deliberately not part
52 of the user interface for this use-case. CMake will compute the appro‐
53 priate compile flags to use by considering the features specified for
54 each target.
55
56 Such compile flags are added even if the compiler supports the particu‐
57 lar feature without the flag. For example, the GNU compiler supports
58 variadic templates (with a warning) even if -std=gnu++98 is used.
59 CMake adds the -std=gnu++11 flag if cxx_variadic_templates is specified
60 as a requirement.
61
62 In the above example, mylib requires cxx_constexpr when it is built
63 itself, but consumers of mylib are not required to use a compiler which
64 supports cxx_constexpr. If the interface of mylib does require the
65 cxx_constexpr feature (or any other known feature), that may be speci‐
66 fied with the PUBLIC or INTERFACE signatures of target_compile_fea‐
67 tures():
68
69 add_library(mylib requires_constexpr.cpp)
70 # cxx_constexpr is a usage-requirement
71 target_compile_features(mylib PUBLIC cxx_constexpr)
72
73 # main.cpp will be compiled with -std=gnu++11 on GNU for cxx_constexpr.
74 add_executable(myexe main.cpp)
75 target_link_libraries(myexe mylib)
76
77 Feature requirements are evaluated transitively by consuming the link
78 implementation. See cmake-buildsystem(7) for more on transitive behav‐
79 ior of build properties and usage requirements.
80
81 Requiring Language Standards
82 In projects that use a large number of commonly available features from
83 a particular language standard (e.g. C++ 11) one may specify a
84 meta-feature (e.g. cxx_std_11) that requires use of a compiler mode
85 that is at minimum aware of that standard, but could be greater. This
86 is simpler than specifying all the features individually, but does not
87 guarantee the existence of any particular feature. Diagnosis of use of
88 unsupported features will be delayed until compile time.
89
90 For example, if C++ 11 features are used extensively in a project’s
91 header files, then clients must use a compiler mode that is no less
92 than C++ 11. This can be requested with the code:
93
94 target_compile_features(mylib PUBLIC cxx_std_11)
95
96 In this example, CMake will ensure the compiler is invoked in a mode of
97 at-least C++ 11 (or C++ 14, C++ 17, …), adding flags such as
98 -std=gnu++11 if necessary. This applies to sources within mylib as
99 well as any dependents (that may include headers from mylib).
100
101 Availability of Compiler Extensions
102 Because the CXX_EXTENSIONS target property is ON by default, CMake uses
103 extended variants of language dialects by default, such as -std=gnu++11
104 instead of -std=c++11. That target property may be set to OFF to use
105 the non-extended variant of the dialect flag. Note that because most
106 compilers enable extensions by default, this could expose cross-plat‐
107 form bugs in user code or in the headers of third-party dependencies.
108
110 Compile features may be preferred if available, without creating a hard
111 requirement. For example, a library may provides alternative implemen‐
112 tations depending on whether the cxx_variadic_templates feature is
113 available:
114
115 #if Foo_COMPILER_CXX_VARIADIC_TEMPLATES
116 template<int I, int... Is>
117 struct Interface;
118
119 template<int I>
120 struct Interface<I>
121 {
122 static int accumulate()
123 {
124 return I;
125 }
126 };
127
128 template<int I, int... Is>
129 struct Interface
130 {
131 static int accumulate()
132 {
133 return I + Interface<Is...>::accumulate();
134 }
135 };
136 #else
137 template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
138 struct Interface
139 {
140 static int accumulate() { return I1 + I2 + I3 + I4; }
141 };
142 #endif
143
144 Such an interface depends on using the correct preprocessor defines for
145 the compiler features. CMake can generate a header file containing
146 such defines using the WriteCompilerDetectionHeader module. The module
147 contains the write_compiler_detection_header function which accepts
148 parameters to control the content of the generated header file:
149
150 write_compiler_detection_header(
151 FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
152 PREFIX Foo
153 COMPILERS GNU
154 FEATURES
155 cxx_variadic_templates
156 )
157
158 Such a header file may be used internally in the source code of a
159 project, and it may be installed and used in the interface of library
160 code.
161
162 For each feature listed in FEATURES, a preprocessor definition is cre‐
163 ated in the header file, and defined to either 1 or 0.
164
165 Additionally, some features call for additional defines, such as the
166 cxx_final and cxx_override features. Rather than being used in #ifdef
167 code, the final keyword is abstracted by a symbol which is defined to
168 either final, a compiler-specific equivalent, or to empty. That way,
169 C++ code can be written to unconditionally use the symbol, and compiler
170 support determines what it is expanded to:
171
172 struct Interface {
173 virtual void Execute() = 0;
174 };
175
176 struct Concrete Foo_FINAL {
177 void Execute() Foo_OVERRIDE;
178 };
179
180 In this case, Foo_FINAL will expand to final if the compiler supports
181 the keyword, or to empty otherwise.
182
183 In this use-case, the CMake code will wish to enable a particular lan‐
184 guage standard if available from the compiler. The CXX_STANDARD target
185 property variable may be set to the desired language standard for a
186 particular target, and the CMAKE_CXX_STANDARD may be set to influence
187 all following targets:
188
189 write_compiler_detection_header(
190 FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
191 PREFIX Foo
192 COMPILERS GNU
193 FEATURES
194 cxx_final cxx_override
195 )
196
197 # Includes foo_compiler_detection.h and uses the Foo_FINAL symbol
198 # which will expand to 'final' if the compiler supports the requested
199 # CXX_STANDARD.
200 add_library(foo foo.cpp)
201 set_property(TARGET foo PROPERTY CXX_STANDARD 11)
202
203 # Includes foo_compiler_detection.h and uses the Foo_FINAL symbol
204 # which will expand to 'final' if the compiler supports the feature,
205 # even though CXX_STANDARD is not set explicitly. The requirement of
206 # cxx_constexpr causes CMake to set CXX_STANDARD internally, which
207 # affects the compile flags.
208 add_library(foo_impl foo_impl.cpp)
209 target_compile_features(foo_impl PRIVATE cxx_constexpr)
210
211 The write_compiler_detection_header function also creates compatibility
212 code for other features which have standard equivalents. For example,
213 the cxx_static_assert feature is emulated with a template and
214 abstracted via the <PREFIX>_STATIC_ASSERT and <PRE‐
215 FIX>_STATIC_ASSERT_MSG function-macros.
216
218 Libraries may provide entirely different header files depending on
219 requested compiler features.
220
221 For example, a header at with_variadics/interface.h may contain:
222
223 template<int I, int... Is>
224 struct Interface;
225
226 template<int I>
227 struct Interface<I>
228 {
229 static int accumulate()
230 {
231 return I;
232 }
233 };
234
235 template<int I, int... Is>
236 struct Interface
237 {
238 static int accumulate()
239 {
240 return I + Interface<Is...>::accumulate();
241 }
242 };
243
244 while a header at no_variadics/interface.h may contain:
245
246 template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
247 struct Interface
248 {
249 static int accumulate() { return I1 + I2 + I3 + I4; }
250 };
251
252 It would be possible to write a abstraction interface.h header contain‐
253 ing something like:
254
255 #include "foo_compiler_detection.h"
256 #if Foo_COMPILER_CXX_VARIADIC_TEMPLATES
257 #include "with_variadics/interface.h"
258 #else
259 #include "no_variadics/interface.h"
260 #endif
261
262 However this could be unmaintainable if there are many files to
263 abstract. What is needed is to use alternative include directories
264 depending on the compiler capabilities.
265
266 CMake provides a COMPILE_FEATURES generator expression to implement
267 such conditions. This may be used with the build-property commands
268 such as target_include_directories() and target_link_libraries() to set
269 the appropriate buildsystem properties:
270
271 add_library(foo INTERFACE)
272 set(with_variadics ${CMAKE_CURRENT_SOURCE_DIR}/with_variadics)
273 set(no_variadics ${CMAKE_CURRENT_SOURCE_DIR}/no_variadics)
274 target_include_directories(foo
275 INTERFACE
276 "$<$<COMPILE_FEATURES:cxx_variadic_templates>:${with_variadics}>"
277 "$<$<NOT:$<COMPILE_FEATURES:cxx_variadic_templates>>:${no_variadics}>"
278 )
279
280 Consuming code then simply links to the foo target as usual and uses
281 the feature-appropriate include directory
282
283 add_executable(consumer_with consumer_with.cpp)
284 target_link_libraries(consumer_with foo)
285 set_property(TARGET consumer_with CXX_STANDARD 11)
286
287 add_executable(consumer_no consumer_no.cpp)
288 target_link_libraries(consumer_no foo)
289
291 CMake is currently aware of the C++ standards and compile features
292 available from the following compiler ids as of the versions specified
293 for each:
294
295 · AppleClang: Apple Clang for Xcode versions 4.4+.
296
297 · Clang: Clang compiler versions 2.9+.
298
299 · GNU: GNU compiler versions 4.4+.
300
301 · MSVC: Microsoft Visual Studio versions 2010+.
302
303 · SunPro: Oracle SolarisStudio versions 12.4+.
304
305 · Intel: Intel compiler versions 12.1+.
306
307 CMake is currently aware of the C standards and compile features avail‐
308 able from the following compiler ids as of the versions specified for
309 each:
310
311 · all compilers and versions listed above for C++.
312
313 · GNU: GNU compiler versions 3.4+
314
315 CMake is currently aware of the C++ standards and their associated
316 meta-features (e.g. cxx_std_11) available from the following compiler
317 ids as of the versions specified for each:
318
319 · Cray: Cray Compiler Environment version 8.1+.
320
321 · PGI: PGI version 12.10+.
322
323 · XL: IBM XL version 10.1+.
324
325 CMake is currently aware of the C standards and their associated
326 meta-features (e.g. c_std_99) available from the following compiler ids
327 as of the versions specified for each:
328
329 · all compilers and versions listed above with only meta-features for
330 C++.
331
332 · TI: Texas Instruments compiler.
333
334 CMake is currently aware of the CUDA standards and their associated
335 meta-features (e.g. cuda_std_11) available from the following compiler
336 ids as of the versions specified for each:
337
338 · NVIDIA: NVIDIA nvcc compiler 7.5+.
339
341 2000-2020 Kitware, Inc. and Contributors
342
343
344
345
3463.17.2 Apr 28, 2020 CMAKE-COMPILE-FEATURES(7)