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