-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Add target_abi
configuration
#2992
Merged
Merged
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
- Feature Name: `cfg-target-abi` | ||
- Start Date: 2020-09-27 | ||
- RFC PR: [rust-lang/rfcs#2992](https://github.com/rust-lang/rfcs/pull/2992) | ||
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) | ||
|
||
# Summary | ||
[summary]: #summary | ||
|
||
This proposes a new `cfg`: `target_abi`, which specifies certain aspects of the | ||
target's [Application Binary Interface (ABI)][abi]. This also adds a | ||
`CARGO_CFG_TARGET_ABI` environment variable for parity with other | ||
`CARGO_CFG_TARGET_*` variables. | ||
|
||
# Motivation | ||
[motivation]: #motivation | ||
|
||
Certain targets are only differentiated by their ABI. For example: the `ios` OS | ||
in combination with the `macabi` ABI denotes targeting Mac Catalyst (iOS on | ||
macOS). The non-`macabi` `x86_64-apple-ios` target is not for Mac Catalyst and | ||
instead is for the iOS simulator, which is a very different environment. | ||
|
||
It is not currently possible to `#[cfg]` against a certain target ABI without | ||
a `build.rs` script to emit a custom `cfg` based on the `TARGET` environment | ||
variable. This is not ideal because: | ||
|
||
- Adding a build script increases compile time and makes a crate incompatible | ||
with certain build systems. | ||
|
||
- Checking `TARGET` is error prone, mainly because the ABI often follows | ||
`target_env` without separation. | ||
|
||
# Guide-level explanation | ||
[guide-level-explanation]: #guide-level-explanation | ||
|
||
This would act like [existing `target_*` configurations][cfg-options]. | ||
|
||
For example: if one had a module with bindings to | ||
[Apple's AppKit](https://developer.apple.com/documentation/appkit), this feature | ||
could be used to ensure the module is available when targeting regular macOS and | ||
Mac Catalyst. | ||
|
||
```rust | ||
#[cfg(any( | ||
target_os = "macos", | ||
all( | ||
target_os = "ios", | ||
target_abi = "macabi", | ||
), | ||
))] | ||
pub mod app_kit; | ||
``` | ||
|
||
This configuration option would also be usable as | ||
`#[cfg_attr(target_abi = "...", attr)]`. | ||
|
||
# Reference-level explanation | ||
[reference-level-explanation]: #reference-level-explanation | ||
|
||
`target_abi` is a key-value option set once with the target's ABI. The value is | ||
similar to the fourth element of the platform's target triple. It often comes | ||
after the `target_env` value. Embedded ABIs such as `gnueabihf` will define | ||
`target_env` as `"gnu"` and `target_abi` as `"eabihf"`. | ||
|
||
Example values: | ||
|
||
- `""` | ||
- `"abi64"` | ||
- `"eabi"` | ||
- `"eabihf"` | ||
- `"macabi"` | ||
|
||
# Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
- Additional metadata for the compiler to keep track of. | ||
|
||
- Like other `cfg`s, this can be manipulated at build time to be a value that | ||
mismatches the actual target. | ||
|
||
# Rationale and alternatives | ||
[rationale-and-alternatives]: #rationale-and-alternatives | ||
|
||
We can keep the existing work-around of checking the `TARGET` environment | ||
variable in a `build.rs` script. However, this is not ideal because: | ||
|
||
- Adding a build script increases compile time and makes a crate incompatible | ||
with certain build systems. | ||
|
||
- Checking `TARGET` is error prone, mainly because the ABI often follows | ||
`target_env` without separation. | ||
|
||
# Prior art | ||
[prior-art]: #prior-art | ||
|
||
- [Target component configurations][cfg-options]: `target_arch`, | ||
`target_vendor`, `target_os`, and `target_env`. | ||
|
||
- `CARGO_CFG_TARGET_*` | ||
[environment variables for `build.rs`](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts). | ||
|
||
# Unresolved questions | ||
[unresolved-questions]: #unresolved-questions | ||
|
||
None. | ||
|
||
# Future possibilities | ||
[future-possibilities]: #future-possibilities | ||
|
||
None. | ||
|
||
[abi]: https://en.wikipedia.org/wiki/Application_binary_interface | ||
[cfg-options]: https://doc.rust-lang.org/reference/conditional-compilation.html#set-configuration-options |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does rustc already have the concept of target ABI internally? If not it seems really important to spell out how exactly this is defined. The concept of ABIs is really poorly understood by developers in my experience. Obviously there's a 1:1 mapping of target : ABI, but the inverse mapping is a little fuzzy to me and I'm not sure how useful it is in practice.
For example, I'm not really aware of an existing convention for talking about the "x86-64 System V ABI" despite it being the ABI used in both x86-64 Linux and macOS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Specifically what I'm interested in is the component that comes after
target_env
in the triple string. What it indicates varies greatly between different targets. On some targets, it indicates the availability of hardware floats (e.g.eabihf
for embedded abi, hardware float). On others, it indicates the running environment (e.g.x86_64-apple-ios-macabi
for iOS apps that target macOS).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To answer my own question, yes it does:
https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/abi/enum.Abi.html
However, this enum seems a lot more like it's describing "calling convention" than "ABI".