Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
c7e099a
build-std: context
davidtwco Jul 22, 2025
a68f085
history: correct default crate built
davidtwco Jul 22, 2025
3d9b399
background: clarify stability of custom targets
davidtwco Jul 23, 2025
0c97a21
background: mention `path`/`git` sources
davidtwco Jul 23, 2025
8765bc5
motivation: clarify these won't all be addressed
davidtwco Jul 23, 2025
64bd0ab
history: clarify `libunwind` source
adamgemmell Jul 28, 2025
a3e92e6
background: clarify not all crates in registry
davidtwco Jul 28, 2025
a99cd20
history: s/virtual/in-memory
davidtwco Jul 28, 2025
786c925
background: split into support/later/won't support
davidtwco Jul 28, 2025
c740a18
background: addl. cargo registry information
davidtwco Jul 31, 2025
7163810
history: mention `no_std` usability issues
davidtwco Jul 31, 2025
396138b
background: user crates use features for std
davidtwco Jul 31, 2025
3939ba0
build-std
davidtwco Jul 22, 2025
a04b43c
1b/future: stable features that will not be usable
davidtwco Jul 22, 2025
8c9797a
1a: document interactions with `no_std`
davidtwco Jul 22, 2025
fc8e473
1b: mention `cargo add` interactions w/ features
davidtwco Jul 22, 2025
e6d9eff
1a: mention `html_root_url` for generated docs
davidtwco Jul 22, 2025
31239ce
1b: remove trailing spaces
adamgemmell Jul 28, 2025
879dc0f
1a: clarify use of `libunwind`
adamgemmell Jul 28, 2025
e384713
1a: mention multi-target projects
adamgemmell Jul 28, 2025
b7ccf2b
1a/2: minor wording tweaks
adamgemmell Jul 28, 2025
0f2d605
1a: `rustc-src` is a default component
adamgemmell Jul 28, 2025
948b09a
1a: clarify built crates
adamgemmell Jul 28, 2025
7567120
1a: mention `compiler-builtins` profile override
adamgemmell Jul 28, 2025
7c2f707
1a: mention `CFLAGS` w/ `compiler-builtins/c`
adamgemmell Jul 28, 2025
6878be5
1a: clarify needing `libc` for `mem` feature
davidtwco Jul 28, 2025
9d0d546
1a/3: move stability guarantees
davidtwco Jul 28, 2025
f78429b
1a: mention stubbed standard library
davidtwco Jul 28, 2025
3315d13
1a: remove unused link
davidtwco Jul 31, 2025
4a786a3
1b: fix future possibility list ordering
davidtwco Jul 31, 2025
a98253b
1a/1b: `no_std` usability solutions
davidtwco Jul 31, 2025
0ec9846
intro: stages have value
davidtwco Aug 6, 2025
6fc1500
intro: clarify Cargo artifact deps
davidtwco Aug 6, 2025
517f6c0
1a: rustc unchanged w/r/t custom targets
davidtwco Aug 6, 2025
d497627
1a: clarify unwind guarantees
davidtwco Aug 6, 2025
fa57ac1
1a: clarify no dylib
davidtwco Aug 6, 2025
7177e96
Changed `build-std=off` to "never"
adamgemmell Aug 7, 2025
a0c0439
Fix broken appendix links
adamgemmell Aug 7, 2025
1fea59a
Move compiler-builtins-c discussion to future possibilities
adamgemmell Aug 7, 2025
ff37ab8
Clarify similarities to other immutable sources
adamgemmell Aug 7, 2025
b3fbeae
Expand rationale for prebuilt stdlib for build scripts/proc_macros
adamgemmell Aug 11, 2025
5aaad19
Link to global caching issue
adamgemmell Aug 11, 2025
8f4f177
Reword unconditional rationale
adamgemmell Aug 11, 2025
c06dbb5
Clarify RUSTFLAGS
adamgemmell Aug 11, 2025
19bf02a
Clarify that any proposals for nightly require an unstable feature
adamgemmell Aug 11, 2025
b87cf3e
Clarify the release profile used
adamgemmell Aug 11, 2025
afdb375
Removed a redundant rationale around build-dependencies
adamgemmell Aug 11, 2025
58884ea
Removed implied direct dependencies
adamgemmell Aug 11, 2025
9355da7
Clarified no-migration rationale and emphasised the increase in
adamgemmell Aug 11, 2025
97fa089
Clarified dev-dependencies
adamgemmell Aug 11, 2025
0678fb5
Formatting fix
adamgemmell Aug 11, 2025
af14747
Add `--builtin` flag to `cargo add`
adamgemmell Aug 11, 2025
f385be6
Clarified inferred deps in the registry index
adamgemmell Aug 11, 2025
d347957
Cargo will perform the check for at least one non-optional builtin
adamgemmell Aug 12, 2025
488aafb
Note the inconsistency with sharing host-mode dependencies
adamgemmell Aug 13, 2025
f19cc6b
Unresolved RUSTFLAGS
adamgemmell Aug 13, 2025
88094de
Rework implicit deps rationale
adamgemmell Aug 14, 2025
39c0f05
Rework manifest compatibility
adamgemmell Aug 14, 2025
1e6184b
Draw attention to build-dependencies
adamgemmell Aug 14, 2025
22a9b85
1a: elaborate on why host-mode uses pre-built std
davidtwco Aug 14, 2025
9c88d2d
1a: clarify no-std section
davidtwco Aug 14, 2025
e93f9aa
1a: clarify status of Cargo caching issue
davidtwco Aug 14, 2025
b279b5b
1a: elaborate on inheriting rustflags
davidtwco Aug 14, 2025
0f6a9ea
1b: correct link syntax
davidtwco Aug 14, 2025
2a330da
1b: simplify unresolved q for build-dependencies
davidtwco Aug 14, 2025
d5e3e64
1b: elaborate on dev-dependencies
davidtwco Aug 14, 2025
725065e
1b: elaborate on `cargo add`/`cargo remove`
davidtwco Aug 14, 2025
97bb251
1b: explicit dependencies for `cargo metadata`
davidtwco Aug 14, 2025
4d7a4d7
1b: published manifest not include inferred deps
davidtwco Aug 14, 2025
6a193bc
1b: clarify pkgid spec
davidtwco Aug 14, 2025
9f8f4ff
1b: mention publish web api endpoint
davidtwco Aug 14, 2025
673069c
1b: add "transitive" for clarification
davidtwco Aug 14, 2025
8127c86
1b: addl. context for registry schema versions
davidtwco Aug 14, 2025
8755a8e
3: mention profile field only working in one ctxt
davidtwco Aug 14, 2025
4a278b8
3: no precedence for precedence
davidtwco Aug 14, 2025
905684d
1b: fix typo
davidtwco Aug 14, 2025
cb098ff
Fix nested list indentation
adamgemmell Aug 15, 2025
dbf57b3
Justify excluded motivations
adamgemmell Aug 15, 2025
418c560
Remove special Cargo handling for c-b-mem
adamgemmell Aug 18, 2025
4a81e02
Clarify shadowing path deps
adamgemmell Aug 18, 2025
69df4d5
Fix heading levels
adamgemmell Aug 21, 2025
c389622
Add unresolved question for rust-src
adamgemmell Aug 21, 2025
316520d
Improve "standard library" terminology
adamgemmell Aug 21, 2025
4114fef
Expand on rustup approach drawbacks
adamgemmell Aug 21, 2025
d9a21cb
Clarify standard library vs std
adamgemmell Aug 21, 2025
fa41db6
Add small introduction to each section listing motivations solved
adamgemmell Aug 21, 2025
1d4d8cd
Mention -Zcrate-attrs wrt restricted_std
adamgemmell Aug 21, 2025
5077aa8
Mention that features aren't additive
adamgemmell Aug 21, 2025
0341199
Various background/history refinements
adamgemmell Aug 28, 2025
84827c3
Cargo config is not just in the home directory
adamgemmell Aug 28, 2025
7e38b8a
Change build-std-crates' definition
adamgemmell Aug 29, 2025
ebe0fb6
Fix typo
adamgemmell Aug 29, 2025
9f75061
Correct extern prelude vs extern crate
adamgemmell Aug 29, 2025
115b0b3
Pass explicit dependencies without noprelude
adamgemmell Sep 23, 2025
8cda9c6
Plan for no_std removal
adamgemmell Sep 23, 2025
3b04dff
Explicitly disallow overriding dependencies except through patch
adamgemmell Sep 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
342 changes: 342 additions & 0 deletions text/0000-build-std/0-introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,342 @@
- 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].

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 and to
[Ed Page][epage] for writing about opaque dependencies.

Thanks to [Jacob Bramley][jacobbramley] for their feedback on early 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 been split into multiple stages. Each stage is a self-contained
proposal building on the previous and aim to have value independent of later
stages. As such, stages should be able to be accepted, implemented and
stabilised sequentially. of other stages.

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. A staged proposal enables
this - each stage can have a small and achievable scope, while still allowing a
reviewer to skip ahead and get a sense of what is planned and how that builds on
what came before.

Later stages may be less detailed and complete than the previous stages and
serve to to indicate the direction that build-std will take and help provide
context for the proposals of earlier stages.

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](./1-background.md)

- Detailed explanations of how relevant and impacted parts of the Rust
toolchain currently work

3. [History](./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](./3-motivation.md)

- Descriptions of the varied problems that build-std has been proposed as a
solution to

5. [Stage 1a: build-std=always](./4-stage-1a.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](./4-stage-1a.md#proposal)

- [Rationale and alternatives](./4-stage-1a.md#rationale-and-alternatives)

- [Unresolved questions](./4-stage-1a.md#unresolved-questions)

- [Future possibilities](./4-stage-1a.md#future-possibilities)

6. [Stage 1b: Explicit dependencies](./5-stage-1b.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](./5-stage-1b.md#proposal)

- [Rationale and alternatives](./5-stage-1b.md#rationale-and-alternatives)

- [Unresolved questions](./5-stage-1b.md#unresolved-questions)

- [Future possibilities](./5-stage-1b.md#future-possibilities)

7. [Stage 2: build-std=compatible](./6-stage-2.md)

- Proposes extending the `build-std` option with a new `compatible` value
which will become the default and automatically rebuilds the standard
library when it is necessary to maintain compatibility with the compiler
flags used by the rest of the crate graph.

- [Proposal](./6-stage-2.md#proposal)

- [Rationale and alternatives](./6-stage-2.md#rationale-and-alternatives)

- [Unresolved questions](./6-stage-2.md#unresolved-questions)

- [Future possibilities](./6-stage-2.md#future-possibilities)

8. [Stage 3: build-std=match-profile](./7-stage-3.md)

- Proposes extending the `build-std` option with new values which
automatically rebuild the standard library to match the user's current
profile.

- [Proposal](./7-stage-3.md#proposal)

- [Rationale and alternatives](./7-stage-3.md#rationale-and-alternatives)

- [Unresolved questions](./7-stage-3.md#unresolved-questions)

- [Future possibilities](./7-stage-3.md#future-possibilities)

9. [Appendix I: Summary of changes](./8-appendix-summary-of-changes.md)

- Summary of each of the changes from each stage which would need implemented
in the Rust toolchain, grouped by the project team whose purview the change
would fall under

10. [Appendix II: Exhaustive literature review](./9-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*](./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, rather than
any specific stage:

## 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.

[davidtwco]: https://github.com/davidtwco
[adamgemmell]: https://github.com/adamgemmell
[ehuss]: https://github.com/ehuss
[epage]: https://github.com/epage
[fee1-dead]: https://github.com/fee1-dead
[jacobbramley]: https://github.com/jacobbramley
[joshtriplett]: https://github.com/joshtriplett
[mati865]: https://github.com/mati865
[petrochenkov]: https://github.com/petrochenkov
[tomassedovic]: https://github.com/tomassedovic
[wesleywiser]: https://github.com/wesleywiser

[why-not-rustup]: https://hackmd.io/@davidtwco/rkYRlKv_1x
Loading