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