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