Skip to content

Commit 13d9a03

Browse files
authored
Merge pull request #383 from Havvy/cfg
Move conditional compilation to its own page
2 parents b8623fa + bf29584 commit 13d9a03

File tree

3 files changed

+107
-96
lines changed

3 files changed

+107
-96
lines changed

Diff for: src/SUMMARY.md

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
- [Crates and source files](crates-and-source-files.md)
2121

22+
- [Conditional compilation](conditional-compilation.md)
23+
2224
- [Items and attributes](items-and-attributes.md)
2325
- [Items](items.md)
2426
- [Modules](items/modules.md)

Diff for: src/attributes.md

+6-96
Original file line numberDiff line numberDiff line change
@@ -232,101 +232,9 @@ See [The Rustdoc Book] for reference material on this attribute.
232232

233233
### Conditional compilation
234234

235-
Sometimes one wants to have different compiler outputs from the same code,
236-
depending on build target, such as targeted operating system, or to enable
237-
release builds.
238-
239-
Configuration options are boolean (on or off) and are named either with a
240-
single identifier (e.g. `foo`) or an identifier and a string (e.g. `foo = "bar"`;
241-
the quotes are required and spaces around the `=` are unimportant). Note that
242-
similarly-named options, such as `foo`, `foo="bar"` and `foo="baz"` may each be
243-
set or unset independently.
244-
245-
Configuration options are either provided by the compiler or passed in on the
246-
command line using `--cfg` (e.g. `rustc main.rs --cfg foo --cfg 'bar="baz"'`).
247-
Rust code then checks for their presence using the `#[cfg(...)]` attribute:
248-
249-
```rust
250-
// The function is only included in the build when compiling for macOS
251-
#[cfg(target_os = "macos")]
252-
fn macos_only() {
253-
// ...
254-
}
255-
256-
// This function is only included when either foo or bar is defined
257-
#[cfg(any(foo, bar))]
258-
fn needs_foo_or_bar() {
259-
// ...
260-
}
261-
262-
// This function is only included when compiling for a unixish OS with a 32-bit
263-
// architecture
264-
#[cfg(all(unix, target_pointer_width = "32"))]
265-
fn on_32bit_unix() {
266-
// ...
267-
}
268-
269-
// This function is only included when foo is not defined
270-
#[cfg(not(foo))]
271-
fn needs_not_foo() {
272-
// ...
273-
}
274-
```
275-
276-
This illustrates some conditional compilation can be achieved using the
277-
`#[cfg(...)]` attribute. `any`, `all` and `not` can be used to assemble
278-
arbitrarily complex configurations through nesting.
279-
280-
The following configurations must be defined by the implementation:
281-
282-
* `target_arch = "..."` - Target CPU architecture, such as `"x86"`,
283-
`"x86_64"` `"mips"`, `"powerpc"`, `"powerpc64"`, `"arm"`, or
284-
`"aarch64"`. This value is closely related to the first element of
285-
the platform target triple, though it is not identical.
286-
* `target_os = "..."` - Operating system of the target, examples
287-
include `"windows"`, `"macos"`, `"ios"`, `"linux"`, `"android"`,
288-
`"freebsd"`, `"dragonfly"`, `"bitrig"` , `"openbsd"` or
289-
`"netbsd"`. This value is closely related to the second and third
290-
element of the platform target triple, though it is not identical.
291-
* `target_family = "..."` - Operating system family of the target, e. g.
292-
`"unix"` or `"windows"`. The value of this configuration option is defined
293-
as a configuration itself, like `unix` or `windows`.
294-
* `unix` - See `target_family`.
295-
* `windows` - See `target_family`.
296-
* `target_env = ".."` - Further disambiguates the target platform with
297-
information about the ABI/libc. Presently this value is either
298-
`"gnu"`, `"msvc"`, `"musl"`, or the empty string. For historical
299-
reasons this value has only been defined as non-empty when needed
300-
for disambiguation. Thus on many GNU platforms this value will be
301-
empty. This value is closely related to the fourth element of the
302-
platform target triple, though it is not identical. For example,
303-
embedded ABIs such as `gnueabihf` will simply define `target_env` as
304-
`"gnu"`.
305-
* `target_endian = "..."` - Endianness of the target CPU, either `"little"` or
306-
`"big"`.
307-
* `target_pointer_width = "..."` - Target pointer width in bits. This is set
308-
to `"32"` for targets with 32-bit pointers, and likewise set to `"64"` for
309-
64-bit pointers.
310-
* `target_has_atomic = "..."` - Set of integer sizes on which the target can perform
311-
atomic operations. Values are `"8"`, `"16"`, `"32"`, `"64"` and `"ptr"`.
312-
* `target_vendor = "..."` - Vendor of the target, for example `apple`, `pc`, or
313-
simply `"unknown"`.
314-
* `test` - Enabled when compiling the test harness (using the `--test` flag).
315-
* `debug_assertions` - Enabled by default when compiling without optimizations.
316-
This can be used to enable extra debugging code in development but not in
317-
production. For example, it controls the behavior of the standard library's
318-
`debug_assert!` macro.
319-
320-
You can also set another attribute based on a `cfg` variable with `cfg_attr`:
321-
322-
```rust,ignore
323-
#[cfg_attr(a, b)]
324-
```
325-
326-
This is the same as `#[b]` if `a` is set by `cfg`, and nothing otherwise.
327-
328-
Lastly, configuration options can be used in expressions by invoking the `cfg!`
329-
macro: `cfg!(a)` evaluates to `true` if `a` is set, and `false` otherwise.
235+
The `cfg` and `cfg_attr` attributes control conditional compilation of [items]
236+
and attributes. See the [conditional compilation] section for reference material
237+
on these attributes.
330238

331239
### Lint check attributes
332240

@@ -572,4 +480,6 @@ You can implement `derive` for your own type through [procedural macros].
572480
[modules]: items/modules.html
573481
[statements]: statements.html
574482
[match expressions]: expressions/match-expr.html
575-
[external blocks]: items/external-blocks.html
483+
[external blocks]: items/external-blocks.html
484+
[items]: items.html
485+
[conditional compilation]: conditional-compilation.html

Diff for: src/conditional-compilation.md

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
## Conditional compilation
2+
3+
Sometimes one wants to have different compiler outputs from the same code,
4+
depending on build target, such as targeted operating system, or to enable
5+
release builds.
6+
7+
Configuration options are boolean (on or off) and are named either with a
8+
single identifier (e.g. `foo`) or an identifier and a string (e.g. `foo = "bar"`;
9+
the quotes are required and spaces around the `=` are unimportant). Note that
10+
similarly-named options, such as `foo`, `foo="bar"` and `foo="baz"` may each be
11+
set or unset independently.
12+
13+
Configuration options are either provided by the compiler or passed in on the
14+
command line using `--cfg` (e.g. `rustc main.rs --cfg foo --cfg 'bar="baz"'`).
15+
Rust code then checks for their presence using the `#[cfg(...)]` [attribute]:
16+
17+
```rust
18+
// The function is only included in the build when compiling for macOS
19+
#[cfg(target_os = "macos")]
20+
fn macos_only() {
21+
// ...
22+
}
23+
24+
// This function is only included when either foo or bar is defined
25+
#[cfg(any(foo, bar))]
26+
fn needs_foo_or_bar() {
27+
// ...
28+
}
29+
30+
// This function is only included when compiling for a unixish OS with a 32-bit
31+
// architecture
32+
#[cfg(all(unix, target_pointer_width = "32"))]
33+
fn on_32bit_unix() {
34+
// ...
35+
}
36+
37+
// This function is only included when foo is not defined
38+
#[cfg(not(foo))]
39+
fn needs_not_foo() {
40+
// ...
41+
}
42+
```
43+
44+
This illustrates some conditional compilation can be achieved using the
45+
`#[cfg(...)]` [attribute]. `any`, `all` and `not` can be used to assemble
46+
arbitrarily complex configurations through nesting.
47+
48+
The following configurations must be defined by the implementation:
49+
50+
* `target_arch = "..."` - Target CPU architecture, such as `"x86"`,
51+
`"x86_64"` `"mips"`, `"powerpc"`, `"powerpc64"`, `"arm"`, or
52+
`"aarch64"`. This value is closely related to the first element of
53+
the platform target triple, though it is not identical.
54+
* `target_os = "..."` - Operating system of the target, examples
55+
include `"windows"`, `"macos"`, `"ios"`, `"linux"`, `"android"`,
56+
`"freebsd"`, `"dragonfly"`, `"bitrig"` , `"openbsd"` or
57+
`"netbsd"`. This value is closely related to the second and third
58+
element of the platform target triple, though it is not identical.
59+
* `target_family = "..."` - Operating system family of the target, e. g.
60+
`"unix"` or `"windows"`. The value of this configuration option is defined
61+
as a configuration itself, like `unix` or `windows`.
62+
* `unix` - See `target_family`.
63+
* `windows` - See `target_family`.
64+
* `target_env = ".."` - Further disambiguates the target platform with
65+
information about the ABI/libc. Presently this value is either
66+
`"gnu"`, `"msvc"`, `"musl"`, or the empty string. For historical
67+
reasons this value has only been defined as non-empty when needed
68+
for disambiguation. Thus on many GNU platforms this value will be
69+
empty. This value is closely related to the fourth element of the
70+
platform target triple, though it is not identical. For example,
71+
embedded ABIs such as `gnueabihf` will simply define `target_env` as
72+
`"gnu"`.
73+
* `target_endian = "..."` - Endianness of the target CPU, either `"little"` or
74+
`"big"`.
75+
* `target_pointer_width = "..."` - Target pointer width in bits. This is set
76+
to `"32"` for targets with 32-bit pointers, and likewise set to `"64"` for
77+
64-bit pointers.
78+
* `target_has_atomic = "..."` - Set of integer sizes on which the target can perform
79+
atomic operations. Values are `"8"`, `"16"`, `"32"`, `"64"` and `"ptr"`.
80+
* `target_vendor = "..."` - Vendor of the target, for example `apple`, `pc`, or
81+
simply `"unknown"`.
82+
* `test` - Enabled when compiling the test harness (using the `--test` flag).
83+
* `debug_assertions` - Enabled by default when compiling without optimizations.
84+
This can be used to enable extra debugging code in development but not in
85+
production. For example, it controls the behavior of the standard library's
86+
`debug_assert!` macro.
87+
88+
You can also set another [attribute] based on a `cfg` variable with `cfg_attr`:
89+
90+
```rust,ignore
91+
#[cfg_attr(a, b)]
92+
```
93+
94+
This is the same as `#[b]` if `a` is set by `cfg`, and nothing otherwise.
95+
96+
Lastly, configuration options can be used in expressions by invoking the `cfg!`
97+
macro: `cfg!(a)` evaluates to `true` if `a` is set, and `false` otherwise.
98+
99+
[attribute]: attributes.html

0 commit comments

Comments
 (0)