Skip to content

Commit 866d6cc

Browse files
tbu-alexcrichton
authored andcommittedFeb 13, 2014
Add documentation for conditional-compilation
This documents in-source conditions using #[cfg(...)] and configurations pre-defined by the compiler. Fix #7962.
1 parent 957fcb3 commit 866d6cc

File tree

1 file changed

+74
-10
lines changed

1 file changed

+74
-10
lines changed
 

‎src/doc/rust.md

+74-10
Original file line numberDiff line numberDiff line change
@@ -1725,31 +1725,95 @@ mod bar {
17251725
pub type int8_t = i8;
17261726
~~~~
17271727

1728-
> **Note:** In future versions of Rust, user-provided extensions to the compiler will be able to interpret attributes.
1729-
> When this facility is provided, the compiler will distinguish between language-reserved and user-available attributes.
1728+
> **Note:** In future versions of Rust, user-provided extensions to the compiler
1729+
> will be able to interpret attributes. When this facility is provided, the
1730+
> compiler will distinguish between language-reserved and user-available
1731+
> attributes.
17301732
1731-
At present, only the Rust compiler interprets attributes, so all attribute
1732-
names are effectively reserved. Some significant attributes include:
1733+
At present, only the Rust compiler interprets attributes, so all attribute names
1734+
are effectively reserved. Some significant attributes include:
17331735

17341736
* The `doc` attribute, for documenting code in-place.
1735-
* The `cfg` attribute, for conditional-compilation by build-configuration.
1737+
* The `cfg` attribute, for conditional-compilation by build-configuration (see
1738+
[Conditional compilation](#conditional-compilation)).
17361739
* The `crate_id` attribute, for describing the package ID of a crate.
17371740
* The `lang` attribute, for custom definitions of traits and functions that are
17381741
known to the Rust compiler (see [Language items](#language-items)).
17391742
* The `link` attribute, for describing linkage metadata for a extern blocks.
17401743
* The `test` attribute, for marking functions as unit tests.
17411744
* The `allow`, `warn`, `forbid`, and `deny` attributes, for
17421745
controlling lint checks (see [Lint check attributes](#lint-check-attributes)).
1743-
* The `deriving` attribute, for automatically generating
1744-
implementations of certain traits.
1746+
* The `deriving` attribute, for automatically generating implementations of
1747+
certain traits.
17451748
* The `inline` attribute, for expanding functions at caller location (see
17461749
[Inline attributes](#inline-attributes)).
1747-
* The `static_assert` attribute, for asserting that a static bool is true at compiletime
1748-
* The `thread_local` attribute, for defining a `static mut` as a thread-local. Note that this is
1749-
only a low-level building block, and is not local to a *task*, nor does it provide safety.
1750+
* The `static_assert` attribute, for asserting that a static bool is true at
1751+
compiletime.
1752+
* The `thread_local` attribute, for defining a `static mut` as a thread-local.
1753+
Note that this is only a low-level building block, and is not local to a
1754+
*task*, nor does it provide safety.
17501755

17511756
Other attributes may be added or removed during development of the language.
17521757

1758+
### Conditional compilation
1759+
1760+
Sometimes one wants to have different compiler outputs from the same code,
1761+
depending on build target, such as targeted operating system, or to enable
1762+
release builds.
1763+
1764+
There are two kinds of configuration options, one that is either defined or not
1765+
(`#[cfg(foo)]`), and the other that contains a string that can be checked
1766+
against (`#[cfg(bar = "baz")]` (currently only compiler-defined configuration
1767+
options can have the latter form).
1768+
1769+
~~~~
1770+
// The function is only included in the build when compiling for OSX
1771+
#[cfg(target_os = "macos")]
1772+
fn macos_only() {
1773+
// ...
1774+
}
1775+
1776+
// This function is only included when either foo or bar is defined
1777+
#[cfg(foo)]
1778+
#[cfg(bar)]
1779+
fn needs_foo_or_bar() {
1780+
// ...
1781+
}
1782+
1783+
// This function is only included when compiling for a unixish OS with a 32-bit
1784+
// architecture
1785+
#[cfg(unix, target_word_size = "32")]
1786+
fn on_32bit_unix() {
1787+
// ...
1788+
}
1789+
~~~~
1790+
1791+
This illustrates some conditional compilation can be achieved using the
1792+
`#[cfg(...)]` attribute. Note that `#[cfg(foo, bar)]` is a condition that needs
1793+
both `foo` and `bar` to be defined while `#[cfg(foo)] #[cfg(bar)]` only needs
1794+
one of `foo` and `bar` to be defined (this resembles in the disjunctive normal
1795+
form). Additionally, one can reverse a condition by enclosing it in a
1796+
`not(...)`, like e. g. `#[cfg(not(target_os = "win32"))]`.
1797+
1798+
To pass a configuration option which triggers a `#[cfg(identifier)]` one can use
1799+
`rustc --cfg identifier`. In addition to that, the following configurations are
1800+
pre-defined by the compiler:
1801+
1802+
* `target_arch = "..."`. Target CPU architecture, such as `"x86"`, `"x86_64"`
1803+
`"mips"`, or `"arm"`.
1804+
* `target_endian = "..."`. Endianness of the target CPU, either `"little"` or
1805+
`"big"`.
1806+
* `target_family = "..."`. Operating system family of the target, e. g.
1807+
`"unix"` or `"windows"`. The value of this configuration option is defined as
1808+
a configuration itself, like `unix` or `windows`.
1809+
* `target_os = "..."`. Operating system of the target, examples include
1810+
`"win32"`, `"macos"`, `"linux"`, `"android"` or `"freebsd"`.
1811+
* `target_word_size = "..."`. Target word size in bits. This is set to `"32"`
1812+
for 32-bit CPU targets, and likewise set to `"64"` for 64-bit CPU targets.
1813+
* `test`. Only set in test builds (`rustc --test`).
1814+
* `unix`. See `target_family`.
1815+
* `windows`. See `target_family`.
1816+
17531817
### Lint check attributes
17541818

17551819
A lint check names a potentially undesirable coding pattern, such as

0 commit comments

Comments
 (0)
Please sign in to comment.