forked from rust-lang/rfcs
-
Notifications
You must be signed in to change notification settings - Fork 0
build-std: release candidate #4
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
Draft
davidtwco
wants to merge
31
commits into
master
Choose a base branch
from
build-std-release-candidate
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
9429391
build-std
davidtwco 428ce01
small wording tweaks
davidtwco 5121a0a
elaborate on content of this part of the RFC
davidtwco 00b3f8f
swap default/alternative in examples
davidtwco d3c2b1a
reword RfL motivation
davidtwco 02f8a08
s/standard_library_support/default_build_std_crate
davidtwco de66272
reword compiler-builtins/mem sections
davidtwco 98ec3e6
reword caching section
davidtwco 77929ca
clarify what later proposals enable
davidtwco 8f82df4
reword cargo vendor changes
davidtwco 7bfca0b
no further required customisation
davidtwco 3214dba
re-order paragraphs
davidtwco 7865b46
no codegen-units changes for compiler-builtins
davidtwco b83f3c9
clarify stability implications of RUSTC_BOOTSTRAP in sysroot
davidtwco 82e054d
+multiple `--target` flags
davidtwco 66a0f58
do not specify compatibility mechanism
davidtwco 328a5f2
consistent `build-std-crates`
davidtwco c48e43d
opaque deps drawback
davidtwco 9719228
standard_library_support
davidtwco cd627f5
cannot replace/patch
davidtwco 47e90e8
skip -p until explicit deps
davidtwco dca995f
+other
davidtwco 503a6d9
unstable dep behind cfg requires feature
davidtwco f436c76
implicit dependencies + multiple dependency tables
davidtwco 0897312
avoid describing relationship between std/alloc/core
davidtwco 74bc861
add unresolved q for public std deps
davidtwco be70a36
elaborate on trade-off for noprelude of explicit builtin deps
davidtwco c25a29a
elaborate on always syntax unresolved q
davidtwco b15595e
build-std=always read together
davidtwco d890a6a
add future possibility for unstable dep behind cfg
davidtwco 754cd4d
fix broken link
davidtwco 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 hidden or 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,329 @@ | ||
- Feature Name: `build-std` | ||
- Start Date: 2025-06-05 | ||
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) | ||
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) | ||
|
||
<!-- | ||
|
||
This document is long and has lots of authors, follow these rules to maintain a | ||
consistent voice and structure: | ||
|
||
Writing style: | ||
|
||
- Text is wrapped at ~80 characters, except for headings | ||
|
||
- Use the passive voice | ||
|
||
- Items in bullet point lists shouldn't end with a period | ||
|
||
- Avoid introducing sections that only include other sections and no written | ||
content within them | ||
|
||
- In the proposals, write as if the feature has already been accepted and | ||
implemented | ||
|
||
- Leave a line between each bullet point | ||
|
||
- With the exception of table of contents-style sections (in this document and | ||
in Appendix I), always use reference-style links | ||
|
||
- Use a spell checker and broken link checker | ||
|
||
- Use 4 spaces for nested bullets, etc. | ||
|
||
Structure: | ||
|
||
- Every header has a reference link defined below it with its anchor. Top-level | ||
sections just match the header text. Other sections have a prefix (e.g. | ||
"rationale-foo", not "foo") | ||
|
||
- Add parentheses with `([?][anchor])` wherever an explanation is justified, | ||
linking to the relevant sub-section in the rationale/alternative section. This | ||
is not required for unresolved questions and future possibilities | ||
|
||
- Each justification/alternative in a section must be included in the bullet | ||
list at the bottom of that sub-section, likewise with unresolved questions and | ||
future possibilities | ||
|
||
- Each future possibility, unresolved question and rationale/alternative must | ||
backlink back to the section that links to it | ||
|
||
- Rationale/alternatives must be in the order that they are referenced in the | ||
text, including in end-of-sub-section lists | ||
|
||
- Add anyone who has provided feedback prior to the publication of the RFC to | ||
the acknowledgements section | ||
|
||
Consistency: | ||
|
||
- Ensure that Appendix I is up-to-date after any changes | ||
|
||
- Appendix II should only reflect the discussion on the cited sources, rather | ||
than the current status quo if it has changed | ||
|
||
- build-std should not be in backticks (i.e. not `build-std`) | ||
|
||
- "pre-built" should always have a hyphen | ||
|
||
- Crate names, Cargo configuration options, compiler flags, file names and | ||
environment variables should always be in a backticks (e.g. `build-std`) | ||
|
||
- Values passed to compiler flags should be in double quotes (e.g. "compatible") | ||
|
||
Git: | ||
|
||
- Try to keep each individual change to a single commit and describe that change | ||
in the commit message | ||
|
||
- This makes it easier to review and catch-up | ||
|
||
- Keep the first line of commit messages limited to 50 characters and the | ||
remaining lines to 74 characters | ||
|
||
--> | ||
|
||
# Summary | ||
[summary]: #summary | ||
|
||
While Rust's pre-built standard library has proven itself sufficient for the | ||
majority of use cases, there are a handful of use cases that are not well | ||
supported: | ||
|
||
1. Rebuilding the standard library to match the user's profile | ||
2. Rebuilding the standard library with ABI-modifying flags | ||
3. Building the standard library for tier three targets | ||
|
||
This RFC proposes a handful of changes to Cargo, the compiler and standard | ||
library with the goal of defining a minimal build-std that has the potential of | ||
being stabilised: | ||
|
||
- Explicitly declaring support for the standard library in target specs | ||
- Explicit and implicit dependencies on the standard library in `Cargo.toml` | ||
- Re-building the standard library when the profile or target modifiers change | ||
|
||
This RFC is co-authored by [David Wood][davidtwco] and | ||
[Adam Gemmell][adamgemmell]. To improve the readability of this RFC, it does not | ||
follow the standard RFC template, while still aiming to capture all of the | ||
salient details that the template encourages. Due to the length of this RFC, it | ||
is split over multiple files to avoid rendering issues and slow loading on some | ||
platforms. | ||
|
||
### Scope | ||
[scope]: #scope | ||
|
||
build-std, as proposed by this RFC, has many restrictions and limitations that | ||
mean it will not support most use cases that those waiting for build-std hope | ||
that it will. This is an explicit and deliberate choice. | ||
|
||
This RFC will focus on resolving the key questions that will enable a MVP of | ||
build-std to be accepted and stabilised. This will lay the foundation for future | ||
proposals to lift restrictions and enable build-std to support more use cases, | ||
without those proposals having to survey the ten+ years of issues, pull requests | ||
and discussion that this RFC has. | ||
|
||
As a general rule, this RFC tries to answer the question "what crates of the | ||
standard library get built and when do they get built" and considers anything | ||
else as likely out-of-scope. | ||
|
||
### Acknowledgements | ||
[acknowledgements]: #acknowledgements | ||
|
||
This RFC would not have been possible without the advice, feedback and support | ||
of [Josh Triplett][joshtriplett], [Eric Huss][ehuss], | ||
[Wesley Wiser][wesleywiser] and [Tomas Sedovic][tomassedovic] throughout this | ||
entire effort. | ||
|
||
Thanks to [mati865] for advising on some of the specifics related to special | ||
object files, [petrochenkov] for his expertise on rustc's dependency loading and | ||
name resolution; [fee1-dead] for their early and thorough reviews; | ||
[Ed Page][epage] for writing about opaque dependencies and his invaluable Cargo | ||
expertise; [Jacob Bramley][jacobbramley] for his feedback on early drafts; as | ||
well as [Amanieu D'Antras][amanieu], [Tobias Bieniek][turbo87], | ||
[Adam Harvey][lawngnome], [James Munns][jamesmunns], | ||
[Jonathan Pallant][thejpster], [Jieyou Xu][jieyouxu], [Jakub Beránek][kobzol], | ||
[Weihang Lo][weihanglo], and [Mark Rousskov][simulacrum] for providing feedback | ||
from their areas of expertise on later drafts. | ||
|
||
### Terminology | ||
[terminology]: #terminology | ||
|
||
The following terminology is used throughout the RFC: | ||
|
||
- "the standard library" is used to refer to multiple of the crates that | ||
constitute the standard library such as `core`, `alloc`, `std`, `test`, | ||
`proc_macro` or their dependencies. | ||
- "std" is used to refer only to the `std` crate, not the entirety of the | ||
standard library | ||
|
||
Throughout the RFC's "Proposal" sections, parentheses with "?" links will be | ||
present that which link the relevant section in the appropriate "Rationale and | ||
alternatives" section to justify a decision or provide alternatives to it. | ||
|
||
Additionally, "note alerts" will be used in the *Proposal* sections to separate | ||
implementation considerations from the core proposal. Implementation detail | ||
should be considered non-normative. These details could change during | ||
implementation and are present solely to demonstrate that the implementation | ||
feasibility has been considered and to provide an example of how implementation | ||
could proceed. | ||
|
||
> [!NOTE] | ||
> | ||
> This is an example of a "note alert" that will be used to separate | ||
> implementation detail from the proposal proper. | ||
|
||
# Contents | ||
[contents]: #contents | ||
|
||
This RFC has two self-contained parts and has been written alongside follow-up | ||
RFCs that extend the infrastructure proposed here. Both parts of this RFC have | ||
value independent of each other while having synergies. | ||
|
||
As build-std is a complex feature with many interdependent design decisions, it | ||
is challenging to draft a proposal that is small enough to have an achievable | ||
scope in the short-to-medium term while making a convincing argument that it is | ||
forward-compatible with any desired future extensions. This RFC contains the | ||
initial infrastructure for build-std and the most basic version of the feature. | ||
Later RFCs will extend this infrastructure to improve usability and utility. | ||
|
||
1. [Summary][summary] (you are here) | ||
|
||
- Introduction to the proposal, its scope, terminology/conventions used and | ||
the structure of the RFC | ||
|
||
- [Proposal-wide rationale and alternatives][rationale-and-alternatives] | ||
|
||
2. [Background](./0000-build-std/1-background.md) | ||
|
||
- Detailed explanations of how relevant and impacted parts of the Rust | ||
toolchain currently work | ||
|
||
3. [History](./0000-build-std/2-history.md) | ||
|
||
- Chronological summary of the various proposals and discussions that have | ||
taken place relating to the ability to rebuild the standard library, and | ||
of the current experimental implementation in Cargo | ||
|
||
4. [Motivation](./0000-build-std/3-motivation.md) | ||
|
||
- Descriptions of the varied problems that build-std has been proposed as a | ||
solution to | ||
|
||
5. [build-std=always](./0000-build-std/4-build-std-always.md) | ||
|
||
- Proposes adding a `build-std = "always|never"` option to the Cargo | ||
configuration which will unconditionally re-build the standard library | ||
crates listed in a new `build-std-crates` option | ||
|
||
- [Proposal](./0000-build-std/4-build-std-always.md#proposal) | ||
|
||
- [Rationale and alternatives](./0000-build-std/4-build-std-always.md#rationale-and-alternatives) | ||
|
||
- [Unresolved questions](./0000-build-std/4-build-std-always.md#unresolved-questions) | ||
|
||
- [Future possibilities](./0000-build-std/4-build-std-always.md#future-possibilities) | ||
|
||
6. [Explicit dependencies](./0000-build-std/5-standard-library-dependencies.md) | ||
|
||
- Proposes supporting explicit dependencies on the standard library crates in | ||
`Cargo.toml` | ||
|
||
- Enables Cargo to determine which standard library crates are required by | ||
the crate graph without `build-std-crates` being set | ||
|
||
- Necessary for future extensions which support public/private standard | ||
library dependencies or enabling features of the standard library | ||
|
||
- [Proposal](./0000-build-std/5-standard-library-dependencies.md#proposal) | ||
|
||
- [Rationale and alternatives](./0000-build-std/5-standard-library-dependencies.md#rationale-and-alternatives) | ||
|
||
- [Unresolved questions](./0000-build-std/5-standard-library-dependencies.md#unresolved-questions) | ||
|
||
- [Future possibilities](./0000-build-std/5-standard-library-dependencies.md#future-possibilities) | ||
|
||
7. [Appendix I: Summary of changes](./0000-build-std/6-appendix-summary-of-changes.md) | ||
|
||
- Summary of each of the changes which would need implemented in the Rust | ||
toolchain, grouped by the project team whose purview the change would fall | ||
under | ||
|
||
8. [Appendix II: Exhaustive literature review](./0000-build-std/7-appendix-literature-review.md) | ||
|
||
- More detailed summaries of the relevant issues, discussions, pull requests | ||
and proposals that comprise the history of the build-std feature since | ||
2015 | ||
|
||
- [*History*](./0000-build-std/2-history.md) aims to summarise this content further and | ||
cover everything that should be necessary to understand the proposal | ||
|
||
# Rationale and alternatives | ||
[rationale-and-alternatives]: #rationale-and-alternatives | ||
|
||
These rationales and alternatives apply to the proposal as-a-whole: | ||
|
||
## Why not do nothing? | ||
[rationale-why-not-do-nothing]: #why-not-do-nothing | ||
|
||
Support for rebuilding the standard library is a long-standing feature request | ||
from subsets of the Rust community and blocks the work of some project teams | ||
(e.g. sanitisers and branch protection in the compiler team, amongst others). | ||
Inaction forces these users to remain on nightly and depend on the unstable | ||
`-Zbuild-std` flag indefinitely. RFCs and discussion dating back to the first | ||
stable release of the language demonstrate the longevity of build-std as a | ||
need. | ||
|
||
## Shouldn't build-std be part of rustup? | ||
[rationale-in-rustup]: #shouldnt-build-std-be-part-of-rustup | ||
|
||
build-std is effectively creating a new sysroot with a customised standard | ||
library. rustup as Rust's toolchain manager has existing machinery to create and | ||
maintain sysroots, and if it could invoke Cargo to build the standard library | ||
then it could create a new toolchain from a build from a `rust-src` component. | ||
rustup would be invoking tools from the next layer of abstraction (Cargo) in the | ||
same way that Cargo invokes tools from the layer of abstraction after it | ||
(rustc). | ||
|
||
A brief prototype of this idea was created and a | ||
[short design document was drafted][why-not-rustup] before concluding that it | ||
would not be possible. With Cargo's artifact dependencies it may be desirable | ||
to build with a different standard library and if rustup was creating different | ||
toolchains per-customised standard library then Cargo would need to have | ||
knowledge of these to switch between them, which isn't possible (and something | ||
of a layering violation). It is also unclear how Cargo would find and use the | ||
uncustomized host sysroot for build scripts and procedural macros. In addition | ||
rustup's knowledge of sysroots and toolchains is limited to the archives it | ||
unpacks - it becoming a part of the build system is not trivial, especially | ||
considering it uses a different versioning system to Cargo, Rust and the | ||
standard library. | ||
|
||
# Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
There are some drawbacks to build-std: | ||
|
||
- build-std overlaps with the initial designs and ideas for opaque dependencies | ||
in Cargo, thereby introducing a risk of constraining or conflicting with the | ||
eventual complete design for opaque dependencies | ||
|
||
[davidtwco]: https://github.com/davidtwco | ||
[adamgemmell]: https://github.com/adamgemmell | ||
[amanieu]: https://github.com/Amanieu | ||
[ehuss]: https://github.com/ehuss | ||
[epage]: https://github.com/epage | ||
[fee1-dead]: https://github.com/fee1-dead | ||
[jacobbramley]: https://github.com/jacobbramley | ||
[jamesmunns]: https://github.com/JamesMunns | ||
[jieyouxu]: https://github.com/jieyouxu | ||
[joshtriplett]: https://github.com/joshtriplett | ||
[kobzol]: https://github.com/kobzol | ||
[lawngnome]: https://github.com/LawnGnome | ||
[mati865]: https://github.com/mati865 | ||
[petrochenkov]: https://github.com/petrochenkov | ||
[simulacrum]: https://github.com/simulacrum | ||
[thejpster]: https://github.com/thejpster | ||
[tomassedovic]: https://github.com/tomassedovic | ||
[turbo87]: https://github.com/Turbo87 | ||
[weihanglo]: https://github.com/weihanglo | ||
[wesleywiser]: https://github.com/wesleywiser | ||
|
||
[why-not-rustup]: https://hackmd.io/@davidtwco/rkYRlKv_1x |
Oops, something went wrong.
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.
This RFC includes two separate but related proposals
build-std=always
I am not seeing any rationale for why these are being conjoined into one RFC. Large RFCs are like large PRs. An area of focus draws everyone's attention, neglecting other topics. Once that area is "resolved enough", people move onto the next one. And so on until everyone is burnt out and we accept or reject it without reviewing important details. This will also make the conversation harder because of how much more there will be. This also pulls teams onto FCPs that aren't relevant.
Examples of splitting related RFCs
I would need to see a strong case made for why these should be kept in the same RFC as having them conjoined will make things harder for all parties involved and, at least for myself, will have less trust in the process.
I could even see splitting
build-std=always
up further to be team focused, layered where at the bottom is infra and lib, then compiler, then cargo. I've not thought through the implications of doing such a split and have no opinion at the moment on what should be done.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.
I've kept both together as they address the same motivations, and share the history, prior art, etc sections. We've wrote all of these together to make sure that the proposals synergise and that everything included is presented in the context of the larger feature/vision it enables.
I'm open to splitting it into a handful of RFCs if we can work out how to partition the content up in a way that makes sense. My plan so far has been that by doing lots of iterations with smaller groups and representatives from each team that we should have addressed a majority of the major feedback we're likely to get and the RFC shouldn't be too surprising to any of the affected teams.
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.
The examples I gave are in a similar boat in terms of synergy and being written together. As for any shared content, I'm unsure how best to handle that.
My response to some of what was discussed was effectively "let's document this and work it out during the RFC with all parties present". Getting feedback in the small is important for faster iteration but it does not replace having a team-wide, project-wide, and community-wide conversation.
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.
I think the easiest way is probably to pick a part of the proposal to make first - probably explicit dependencies? - and then include all the context/history/etc with that, and then just reference that RFC's context/history/prior art sections from everything that follows.
👍
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.
I'd post both at once. I feel like "explicit dependencies" could even stand on its own separate from build-std.
Alternatively, we create another RFC that is laying down the build-std project constraints. Not quite a eRFC but not quite a behavior-specifying RFC, making it so there are (at least) three proposals in flight.
Uh oh!
There was an error while loading. Please reload this page.
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.
I really like that as an approach. Most of the sections that would make up that RFC are basically already ready and could be posted much sooner than the rest of the RFC, then we can just post everything else in whatever chunks make most sense.