-
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
Flexible target specification #131
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
- Start Date: 2014-06-18 | ||
- RFC PR #: (leave this empty) | ||
- Rust Issue #: (leave this empty) | ||
|
||
# Summary | ||
|
||
*Note:* This RFC discusses the behavior of `rustc`, and not any changes to the | ||
language. | ||
|
||
Change how target specification is done to be more flexible for unexpected | ||
usecases. Additionally, add support for the "unknown" OS in target triples, | ||
providing a minimum set of target specifications that is valid for bare-metal | ||
situations. | ||
|
||
# Motivation | ||
|
||
One of Rust's important use cases is embedded, OS, or otherwise "bare metal" | ||
software. At the moment, we still depend on LLVM's split-stack prologue for | ||
stack safety. In certain situations, it is impossible or undesirable to | ||
support what LLVM requires to enable this (on x86, a certain thread-local | ||
storage setup). Additionally, porting `rustc` to a new platform requires | ||
modifying the compiler, adding a new OS manually. | ||
|
||
# Detailed design | ||
|
||
A target triple consists of three strings separated by a hyphen, with a | ||
possible fourth string at the end preceded by a hyphen. The first is the | ||
architecture, the second is the "vendor", the third is the OS type, and the | ||
optional fourth is environment type. In theory, this specifies precisely what | ||
platform the generated binary will be able to run on. All of this is | ||
determined not by us but by LLVM and other tools. When on bare metal or a | ||
similar environment, there essentially is no OS, and to handle this there is | ||
the concept of "unknown" in the target triple. When the OS is "unknown", | ||
no runtime environment is assumed to be present (including things such as | ||
dynamic linking, threads/thread-local storage, IO, etc). | ||
|
||
Rather than listing specific targets for special treatment, introduce a | ||
general mechanism for specifying certain characteristics of a target triple. | ||
Redesign how targets are handled around this specification, including for the | ||
built-in targets. Extend the `--target` flag to accept a file name of a target | ||
specificatoin. A table of the target specification flags and their meaning: | ||
|
||
* `data-layout`: The [LLVM data | ||
layout](http://llvm.org/docs/LangRef.html#data-layout) to use. Mostly included | ||
for completeness; changing this is unlikely to be used. | ||
* `link-args`: Arguments to pass to the linker, unconditionally. | ||
* `cpu`: Default CPU to use for the target, overridable with `-C target-cpu` | ||
* `features`: Default target features to enable, augmentable with `-C | ||
target-features`. | ||
* `dynamic-linking-available`: Whether the `dylib` crate type is allowed. | ||
* `split-stacks-supported`: Whether there is runtime support that will allow | ||
LLVM's split stack prologue to function as intended. | ||
* `target-name`: What name to use for `targ_os` for use in `cfg` and for | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it worth specifying target arch too? Things like 'thumbv6m' are changed into 'thumb' in rustc at the moment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice catch, good idea. I'll take a pass over target_foo today and see what else is worth specifying. |
||
passing to LLVM. | ||
* `relocation-model`: What relocation model to use by default. | ||
|
||
Rather than hardcoding a specific set of behaviors per-target, with no | ||
recourse for escaping them, the compiler would also use this mechanism when | ||
deciding how to build for a given target. The process would look like: | ||
|
||
1. Look up the target triple in an internal map, and load that configuration | ||
if it exists. If that fails, check if the target name exists as a file, and | ||
try loading that. If the file does not exist, look up `<target>.json` in | ||
the `RUST_TARGET_PATH`, which is a colon-separated list of directories | ||
defaulting to `/etc/rustc`. | ||
2. If `-C linker` is specified, use that instead of the target-specified | ||
linker. | ||
3. If `-C link-args` is given, add those to the ones specified by the target. | ||
4. If `-C target-cpu` is specified, replace the target `cpu` with it. | ||
5. If `-C target-feature` is specified, add those to the ones specified by the | ||
target. | ||
6. If `-C relocation-model` is specified, replace the target | ||
`relocation-model` with it. | ||
|
||
|
||
Then during compilation, this information is used at the proper places rather | ||
than matching against an enum listing the OSes we recognize. | ||
|
||
The complete set of target configuration flags would be mixed into the SVH | ||
for that crate, but would not include modifications given with `-C`. | ||
|
||
# Drawbacks | ||
|
||
More complexity. However, this is very flexible and allows one to use Rust on | ||
a new or non-standard target *incredibly easy*, without having to modify the | ||
compiler. rustc is the only compiler I know of that would allow that. | ||
|
||
# Alternatives | ||
|
||
A less holistic approach would be to just allow disabling split stacks on a | ||
per-crate basis. Another solution could be adding a family of targets, | ||
`<arch>-unknown-unknown`, which omits all of the above complexity but does not | ||
allow extending to new targets easily. `-T` can easily be extended for the | ||
future needs of other targets. |
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.
:set spell