]> git.proxmox.com Git - rustc.git/blame - src/doc/reference/src/conditional-compilation.md
New upstream version 1.41.1+dfsg1
[rustc.git] / src / doc / reference / src / conditional-compilation.md
CommitLineData
13cf67c4 1# Conditional compilation
b7449926 2
13cf67c4
XL
3> **<sup>Syntax</sup>**\
4> _ConfigurationPredicate_ :\
5> &nbsp;&nbsp; &nbsp;&nbsp; _ConfigurationOption_\
6> &nbsp;&nbsp; | _ConfigurationAll_\
7> &nbsp;&nbsp; | _ConfigurationAny_\
8> &nbsp;&nbsp; | _ConfigurationNot_
9>
10> _ConfigurationOption_ :\
11> &nbsp;&nbsp; [IDENTIFIER]&nbsp;(`=` ([STRING_LITERAL] | [RAW_STRING_LITERAL]))<sup>?</sup>
12>
13> _ConfigurationAll_\
14> &nbsp;&nbsp; `all` `(` _ConfigurationPredicateList_<sup>?</sup> `)`
15>
16> _ConfigurationAny_\
17> &nbsp;&nbsp; `any` `(` _ConfigurationPredicateList_<sup>?</sup> `)`
18>
19> _ConfigurationNot_\
20> &nbsp;&nbsp; `not` `(` _ConfigurationPredicate_ `)`
21>
22> _ConfigurationPredicateList_\
23> &nbsp;&nbsp; _ConfigurationPredicate_ (`,` _ConfigurationPredicate_)<sup>\*</sup> `,`<sup>?</sup>
b7449926 24
13cf67c4
XL
25*Conditionally compiled source code* is source code that may or may not be
26considered a part of the source code depending on certain conditions. <!-- This
27definition is sort of vacuous --> Source code can be conditionally compiled
e1599b0c 28using the [attributes] [`cfg`] and [`cfg_attr`] and the built-in [`cfg` macro].
13cf67c4
XL
29These conditions are based on the target architecture of the compiled crate,
30arbitrary values passed to the compiler, and a few other miscellaneous things
31further described below in detail.
b7449926 32
13cf67c4
XL
33Each form of conditional compilation takes a _configuration predicate_ that
34evaluates to true or false. The predicate is one of the following:
35
36* A configuration option. It is true if the option is set and false if it is
37 unset.
38* `all()` with a comma separated list of configuration predicates. It is false
39 if at least one predicate is false. If there are no predicates, it is true.
40* `any()` with a comma separated list of configuration predicates. It is true
41 if at least one predicate is true. If there are no predicates, it is false.
42* `not()` with a configuration predicate. It is true if its predicate is false
43 and false if its predicate is true.
44
45_Configuration options_ are names and key-value pairs that are either set or
46unset. Names are written as a single identifier such as, for example, `unix`.
47Key-value pairs are written as an identifier, `=`, and then a string. For
48example, `target_arch = "x86_64"` is a configuration option.
49
50> **Note**: Whitespace around the `=` is ignored. `foo="bar"` and `foo = "bar"`
51> are equivalent configuration options.
52
53Keys are not unique in the set of key-value configuration options. For example,
54both `feature = "std"` and `feature = "serde"` can be set at the same time.
55
56## Set Configuration Options
57
58Which configuration options are set is determined statically during the
59compilation of the crate. Certain options are _compiler-set_ based on data
60about the compilation. Other options are _arbitrarily-set_, set based on input
61passed to the compiler outside of the code. It is not possible to set a
62configuration option from within the source code of the crate being compiled.
63
64> **Note**: For `rustc`, arbitrary-set configuration options are set using the
65> [`--cfg`] flag.
66
67<div class="warning">
68
69Warning: It is possible for arbitrarily-set configuration options to have the
70same value as compiler-set configuration options. For example, it is possible
71to do `rustc --cfg "unix" program.rs` while compiling to a Windows target, and
72have both `unix` and `windows` configuration options set at the same time. It
73is unwise to actually do this.
74
75</div>
76
77### `target_arch`
78
79Key-value option set once with the target's CPU architecture. The value is
80similar to the first element of the platform's target triple, but not
81identical.
82
83Example values:
84
85* `"x86"`
86* `"x86_64"`
87* `"mips"`
88* `"powerpc"`
89* `"powerpc64"`
90* `"arm"`
91* `"aarch64"`
92
532ac7d7
XL
93### `target_feature`
94
95Key-value option set for each platform feature available for the current
96compilation target.
97
98Example values:
99
100* `"avx"`
101* `"avx2"`
102* `"crt-static"`
103* `"rdrand"`
104* `"sse"`
105* `"sse2"`
106* `"sse4.1"`
107
108See the [`target_feature` attribute] for more details on the available
109features. An additional feature of `crt-static` is available to the
110`target_feature` option to indicate that a [static C runtime] is available.
111
13cf67c4
XL
112### `target_os`
113
114Key-value option set once with the target's operating system. This value is
115similar to the second and third element of the platform's target triple.
116
117Example values:
118
119* `"windows"`
120* `"macos"`
121* `"ios"`
122* `"linux"`
123* `"android"`
124* `"freebsd"`
125* `"dragonfly"`
13cf67c4
XL
126* `"openbsd"`
127* `"netbsd"`
128
129### `target_family`
130
131Key-value option set at most once with the target's operating system value.
132
133Example values:
134
135* `"unix"`
136* `"windows"`
137
138### `unix` and `windows`
139
140`unix` is set if `target_family = "unix"` is set and `windows` is set if
141`target_family = "windows"` is set.
142
143### `target_env`
144
145Key-value option set with further disambiguating information about the target
146platform with information about the ABI or `libc` used. For historical reasons,
147this value is only defined as not the empty-string when actually needed for
148disambiguation. Thus, for example, on many GNU platforms, this value will be
149empty. This value is similar to the fourth element of the platform's target
150triple. One difference is that embedded ABIs such as `gnueabihf` will simply
151define `target_env` as `"gnu"`.
152
153Example values:
154
155* `""`
156* `"gnu"`
157* `"msvc"`
158* `"musl"`
532ac7d7 159* `"sgx"`
13cf67c4
XL
160
161### `target_endian`
162
163Key-value option set once with either a value of "little" or "big" depending
164on the endianness of the target's CPU.
165
166### `target_pointer_width`
167
168Key-value option set once with the target's pointer width in bits. For example,
169for targets with 32-bit pointers, this is set to `"32"`. Likewise, it is set
170to `"64"` for targets with 64-bit pointers.
171
532ac7d7 172<!-- Are there targets that have a different bit number? -->
13cf67c4
XL
173
174### `target_vendor`
175
176Key-value option set once with the vendor of the target.
177
9fa01778 178Example values:
13cf67c4
XL
179
180* `"apple"`
532ac7d7 181* `"fortanix"`
13cf67c4
XL
182* `"pc"`
183* `"unknown"`
184
185### `test`
186
187Enabled when compiling the test harness. Done with `rustc` by using the
532ac7d7 188[`--test`] flag. See [Testing] for more on testing support.
13cf67c4
XL
189
190### `debug_assertions`
191
192Enabled by default when compiling without optimizations.
193This can be used to enable extra debugging code in development but not in
194production. For example, it controls the behavior of the standard library's
195[`debug_assert!`] macro.
196
197### `proc_macro`
198
199Set when the crate being compiled is being compiled with the `proc_macro`
200[crate type].
201
202## Forms of conditional compilation
203
204### The `cfg` attribute
205
206> **<sup>Syntax</sup>**\
207> _CfgAttrAttribute_ :\
208> &nbsp;&nbsp; `cfg` `(` _ConfigurationPredicate_ `)`
209
210<!-- should we say they're active attributes here? -->
211
212The `cfg` [attribute] conditionally includes the thing it is attached to based
213on a configuration predicate.
214
215It is written as `cfg`, `(`, a configuration predicate, and finally `)`.
216
217If the predicate is true, the thing is rewritten to not have the `cfg` attribute
218on it. If the predicate is false, the thing is removed from the source code.
219
220Some examples on functions:
b7449926
XL
221
222```rust
223// The function is only included in the build when compiling for macOS
224#[cfg(target_os = "macos")]
225fn macos_only() {
226 // ...
227}
228
229// This function is only included when either foo or bar is defined
230#[cfg(any(foo, bar))]
231fn needs_foo_or_bar() {
232 // ...
233}
234
235// This function is only included when compiling for a unixish OS with a 32-bit
236// architecture
237#[cfg(all(unix, target_pointer_width = "32"))]
238fn on_32bit_unix() {
239 // ...
240}
241
242// This function is only included when foo is not defined
243#[cfg(not(foo))]
244fn needs_not_foo() {
245 // ...
246}
247```
248
dc9dc135 249The `cfg` attribute is allowed anywhere attributes are allowed.
13cf67c4
XL
250
251### The `cfg_attr` attribute
252
253> **<sup>Syntax</sup>**\
254> _CfgAttrAttribute_ :\
532ac7d7
XL
255> &nbsp;&nbsp; `cfg_attr` `(` _ConfigurationPredicate_ `,` _CfgAttrs_<sup>?</sup> `)`
256>
257> _CfgAttrs_ :\
258> &nbsp;&nbsp; [_Attr_]&nbsp;(`,` [_Attr_])<sup>\*</sup> `,`<sup>?</sup>
13cf67c4
XL
259
260The `cfg_attr` [attribute] conditionally includes [attributes] based on a
261configuration predicate.
262
532ac7d7
XL
263When the configuration predicate is true, this attribute expands out to the
264attributes listed after the predicate. For example, the following module will
13cf67c4 265either be found at `linux.rs` or `windows.rs` based on the target.
b7449926 266
60c5eb7d 267<!-- ignore: `mod` needs multiple files -->
b7449926 268```rust,ignore
13cf67c4
XL
269#[cfg_attr(linux, path = "linux.rs")]
270#[cfg_attr(windows, path = "windows.rs")]
271mod os;
b7449926
XL
272```
273
532ac7d7
XL
274Zero, one, or more attributes may be listed. Multiple attributes will each be
275expanded into separate attributes. For example:
276
60c5eb7d 277<!-- ignore: fake attributes -->
532ac7d7
XL
278```rust,ignore
279#[cfg_attr(feature = "magic", sparkles, crackles)]
280fn bewitched() {}
281
282// When the `magic` feature flag is enabled, the above will expand to:
283#[sparkles]
284#[crackles]
285fn bewitched() {}
286```
287
13cf67c4 288> **Note**: The `cfg_attr` can expand to another `cfg_attr`. For example,
e1599b0c 289> `#[cfg_attr(linux, cfg_attr(feature = "multithreaded", some_other_attribute))]`
13cf67c4
XL
290> is valid. This example would be equivalent to
291> `#[cfg_attr(all(linux, feature ="multithreaded"), some_other_attribute)]`.
292
dc9dc135 293The `cfg_attr` attribute is allowed anywhere attributes are allowed.
13cf67c4
XL
294
295### The `cfg` macro
296
297The built-in `cfg` macro takes in a single configuration predicate and evaluates
298to the `true` literal when the predicate is true and the `false` literal when
299it is false.
b7449926 300
13cf67c4
XL
301For example:
302
303```rust
304let machine_kind = if cfg!(unix) {
305 "unix"
306} else if cfg!(windows) {
307 "windows"
308} else {
309 "unknown"
310};
311
312println!("I'm running on a {} machine!", machine_kind);
313```
b7449926 314
416331ca
XL
315[IDENTIFIER]: identifiers.md
316[RAW_STRING_LITERAL]: tokens.md#raw-string-literals
317[STRING_LITERAL]: tokens.md#string-literals
318[Testing]: attributes/testing.md
319[_Attr_]: attributes.md
320[`--cfg`]: ../rustc/command-line-arguments.html#--cfg-configure-the-compilation-environment
321[`--test`]: ../rustc/command-line-arguments.html#--test-build-a-test-harness
13cf67c4
XL
322[`cfg`]: #the-cfg-attribute
323[`cfg` macro]: #the-cfg-macro
324[`cfg_attr`]: #the-cfg_attr-attribute
325[`debug_assert!`]: ../std/macro.debug_assert.html
416331ca
XL
326[`target_feature` attribute]: attributes/codegen.md#the-target_feature-attribute
327[attribute]: attributes.md
328[attributes]: attributes.md
329[crate type]: linkage.md
330[static C runtime]: linkage.md#static-and-dynamic-c-runtimes