Skip to content

Commit 9f52d28

Browse files
committed
merge RFC 3239
2 parents ac6a2d2 + abdb917 commit 9f52d28

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

text/3239-cfg-target.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
- Feature Name: `cfg-target`
2+
- Start Date: 2020-09-27
3+
- RFC PR: [rust-lang/rfcs#3239](https://github.com/rust-lang/rfcs/pull/3239)
4+
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/96901)
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
This proposes a new `cfg`: `target`, which matches the entire target triple
10+
string (e.g. `arm-unknown-linux-gnueabihf`). This also adds a `CARGO_CFG_TARGET`
11+
environment variable for parity with other `CARGO_CFG_*` variables.
12+
13+
In addition, this proposes a shorthand `cfg(target(...))` to match multiple
14+
components of a target string at once.
15+
16+
# Motivation
17+
[motivation]: #motivation
18+
19+
To `#[cfg]` against a specific target, a `build.rs` script is required to emit a
20+
custom `cfg` based on the `TARGET` environment variable. Adding a build script
21+
increases compile time and makes a crate incompatible with certain build
22+
systems.
23+
24+
Otherwise, all available components would need to be specified separately:
25+
`target_arch`, `target_vendor`, `target_os`, `target_env` and `target_abi`.
26+
This can be very cumbersome. Note that the target ABI cannot currently be
27+
`#[cfg]`-ed against, so a `build.rs` is still necessary to match all target
28+
components.
29+
30+
# Guide-level explanation
31+
[guide-level-explanation]: #guide-level-explanation
32+
33+
This would act like existing `target_*` configurations (except `target_feature`)
34+
but match against all components.
35+
36+
```rust
37+
#[cfg(target = "x86_64-apple-ios-macabi")]
38+
mod mac_catalyst;
39+
```
40+
41+
This includes `#[cfg_attr(target = "...", attr)]`.
42+
43+
It would also support to specify each `target_*` inside a new `target`
44+
attribute as follows:
45+
46+
```rust
47+
// So we can for example rewrite:
48+
#[cfg(all(target_os = "linux", target_arch = "arm"))]
49+
// as:
50+
#[cfg(target(os = "linux", arch = "arm"))]
51+
```
52+
53+
# Reference-level explanation
54+
[reference-level-explanation]: #reference-level-explanation
55+
56+
`target` is a key-value option set once with the target's Rust triple.
57+
58+
Example values:
59+
60+
- `"aarch64-apple-darwin"`
61+
- `"arm-unknown-linux-gnueabihf"`
62+
- `"x86_64-apple-ios-macabi"`
63+
- `"x86_64-pc-windows-gnu"`
64+
- `"x86_64-pc-windows-msvc"`
65+
- `"x86_64-unknown-linux-gnu"`
66+
67+
## Semantics of target with attributes
68+
69+
The shorthand form of `#[cfg(target(os = "linux))]` is expanded and entirely
70+
equivalent to `#[cfg(target_os = "linux")]` (and so on for `arch` and the other
71+
potential attributes).
72+
73+
# Drawbacks
74+
[drawbacks]: #drawbacks
75+
76+
- Configuring against specific targets can be overly strict and could make
77+
certain `#[cfg]`s miss similar configurations with small changes.
78+
79+
For example: `aarch64-unknown-none` does not match
80+
`aarch64-unknown-none-softfloat`, yet one would likely want to include ABI
81+
variants. The same concern applies to the target vendor.
82+
83+
A potential solution would be to allow glob matching (e.g.
84+
`aarch64-unknown-none*`), but that is not within the scope of this proposal
85+
because it is not currently used in other `#[cfg]`s.
86+
87+
- The `CARGO_CFG_TARGET` environment variable is redundant with the existing
88+
`TARGET`. However, including it would be consistent with other `CARGO_CFG_*`
89+
variables.
90+
91+
# Rationale and alternatives
92+
[rationale-and-alternatives]: #rationale-and-alternatives
93+
94+
We can keep the existing work-around of checking the `TARGET` environment
95+
variable in a `build.rs` script. However, that increases compile time and makes
96+
a crate incompatible with certain build systems.
97+
98+
# Prior art
99+
[prior-art]: #prior-art
100+
101+
- [Target component configurations](https://doc.rust-lang.org/reference/conditional-compilation.html#set-configuration-options):
102+
`target_arch`, `target_vendor`, `target_os`, and `target_env`.
103+
104+
- `TARGET` and `CARGO_CFG_TARGET_*`
105+
[environment variables for `build.rs`](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts).
106+
107+
# Unresolved questions
108+
[unresolved-questions]: #unresolved-questions
109+
110+
- How do we ensure a project does not miss configurations similar to the ones
111+
being `#[cfg]`-ed against with this feature? Perhaps this should be added as a
112+
Clippy lint that's off by default.
113+
114+
# Future possibilities
115+
[future-possibilities]: #future-possibilities
116+
117+
This would enable `#[cfg]`-ing against a specific target ABI (e.g. `macabi`,
118+
`eabihf`). However, that is not the motivation for this proposal and should be
119+
handled separately.

0 commit comments

Comments
 (0)