-
Notifications
You must be signed in to change notification settings - Fork 1.7k
build-std: always #3874
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
base: master
Are you sure you want to change the base?
build-std: always #3874
Conversation
|
|
||
| - [*Allow reusing sysroot artifacts if available*][future-reuse-sysroot] | ||
|
|
||
| [Opaque dependencies]: https://hackmd.io/@epage/ByGfPtRell |
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 has moved to a more official place
| [Opaque dependencies]: https://hackmd.io/@epage/ByGfPtRell | |
| [Opaque dependencies]: https://github.com/rust-lang/cargo/issues/3573#issuecomment-3498262549 |
|
|
||
| > [!NOTE] | ||
| > | ||
| > Inspired by the concept of [opaque dependencies][Opaque dependencies], the |
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.
@nicoburns brought up on reddit the idea of cargo clean not affecting opaque dependencies, requiring some other step to clean them (maybe a cargo clean -p std). Alternatively, we may get this "for free" with rust-lang/cargo#5931.
I lean towards keeping cargo clean the same for now but might be worth calling this question out somewhere.
|
|
||
| ```toml | ||
| [build] | ||
| build-std = { when = "always", crates = "std" } |
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.
crates being plural but only taking a single string argument rather than a list/table reads a bit odd. Not sure what to do about that given that only specifying the "max" crate to be build and implying dependencies sounds reasonable.
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.
Maybe build-std.up-to = "std"? Since crates = "std" is the default, it makes a lot of sense for people to say, for example, build-std = { when = "always", up-to = "alloc" }.
|
As a heads up, we are planning to start an FCP proposal on this RFC shortly after #3873 (build-std context) has been approved. |
| invoked ([?][rationale-implied-bootstrap]). Cargo will not need to use | ||
| `RUSTC_BOOTSTRAP` when compiling the standard library with a stable toolchain. | ||
| The standard library's dependencies will not be permitted to use build probes to | ||
| detect whether a nightly version is being used. |
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 went through all build scripts in dependencies we have. The libc crate detects both the rustc version and if it is a nightly version. It seems like it doesn't actually use the latter for anything though. The object crate also detects rustc version. Nothing else seems to be detecting the rustc version that I could see.
| Ideally, a crate should be able to provide alternate memory symbols and disable | ||
| `compiler_builtins`' symbols for the entire crate graph by enabling a feature | ||
| (e.g. `std`/`libc` could do this) - this is what an `external-mem` feature | ||
| enables. |
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.
Until external-mem automatically gets enabled for all targets with a libc implementation, this inversion of the mem feature would cause a silent performance hit for those targets, while previously you would get a loud failure, which IMO is preferable.
| [preventing-implicit-sysroot-dependencies]: #preventing-implicit-sysroot-dependencies | ||
|
|
||
| Cargo will pass a new flag to rustc which will prevent rustc from loading | ||
| top-level dependencies from the sysroot ([?][rationale-root-sysroot-deps]). |
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.
--sysroot /dev/null is already effectively that except for that also blocking discovery of self-contained artifacts.
| Vendoring the standard library is possible since it currently has its own | ||
| workspace, allowing the dependencies of just the standard library crates (and | ||
| not the compiler or associated tools in `rust-lang/rust`) to be easily packaged. | ||
| Doing so has multiple advantages.. |
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 fully agree we should be vendoring the standard library dependencies. Actually implementing that is non-trivial however: #t-cargo > vendoring for -Zbuild-std Setting the vendoring using .cargo/config.toml doesn't work and I couldn't figure out how to make -Zbuild-std respect it. Next thing I want to try is patching library/Cargo.toml to add a [patch.crates-io] section. Perhaps the standard library workspace is still considered enough of a workspace by -Zbuild-std for that to work.
|
|
||
| For example, Rust's project goal to enable Rust for Linux to build using only a | ||
| stable toolchain would require that it be possible to build `core` without | ||
| nightly. |
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.
An alternative design would be to have a rustc flag which makes it build all requested standard library crates and put them in a specified directory. And then another flag to load standard library crates from said directory when compiling user code. Rustc would then be responsible for all orchestration and we wouldn't require every build system to implement a Cargo.toml parser and build.rs output parser. Said parser would need to be updated every time we use a new cargo feature in the standard library, which would mean we can't use any new cargo features ever without breaking some build system if said build system is responsible for orchestrating the compilation of the standard library.
Handling this all inside rustc itself would allow much more freedom for us (both using newer cargo features and reorganizing the standard library) and be easier for alternative build systems. If we don't want all this logic to be inside rustc itself, we could also put the build logic in a separate rustc-sysroot-build binary (which could for example use cargo as library or binary to build the standard library as regular cargo project and then copy out the libraries into the output directory) and only keep the flag to use the built standard library inside rustc, with regular cargo invoking rustc-sysroot-build first.
| dependencies of `profiler-builtins` so that build-std can reliably compile the | ||
| `profiler-builtins` crate regardless of the environment. Alternatively, | ||
| stability guarantees could be adjusted to set expectations that some parts of | ||
| the standard library may not build without external system dependencies. |
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 me the fact that profiler-builtins is even a crate at all rather than a C static library is a hack to enable building the profiler-rt C library within the context of a regular cargo build of the standard library. If we give up on supporting that, we should just get rid of profiler-builtins as a crate entirely and have rustc directly load a .a file. That would also simplify some logic inside rustc I think. Currently we have to inject a dependency on profiler-builtins quite early already rather than delaying this to the linker code.
| change (e.g. switching between stable and nightly and back). The `dylib` is only | ||
| linked against when `-Cprefer-dynamic` is used. build-std will initially be | ||
| conservative and not include the `dylib` and `-Cprefer-dynamic` would fail | ||
| compilation. |
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'm pretty sure -Cprefer-dynamic would fallback to static linking rather than failing compilation.
As part of rust-lang#3883, we have switched the template to stop using level-1 headings which isn't the way mdbook is intended to be used.
…json, r=Kivooeo Destabilise `target-spec-json` Per rust-lang/compiler-team#944: > Per rust-lang#71009, the ability to load target spec JSONs was stabilised accidentally. Within the team, we've always considered the format to be unstable and have changed it freely. This has been feasible as custom targets can only be used with core, like any other target, and so custom targets de-facto require nightly to be used (i.e. to build core manually or use Cargo's -Zbuild-std). > > Current build-std RFCs (rust-lang/rfcs#3873, rust-lang/rfcs#3874) propose a mechanism for building core on stable (at the request of Rust for Linux), which combined with a stable target-spec-json format, permit the current format to be used much more widely on stable toolchains. This would prevent us from improving the format - making it less tied to LLVM, switching to TOML, enabling keys in the spec to be stabilised individually, etc. > > De-stabilising the format gives us the opportunity to improve the format before it is too challenging to do so. Internal company toolchains and projects like Rust for Linux already use target-spec-json, but must use nightly at some point while doing so, so while it could be inconvenient for those users to destabilise this, it is hoped that an minimal alternative that we could choose to stabilise can be proposed relatively quickly.
…json, r=Kivooeo Destabilise `target-spec-json` Per rust-lang/compiler-team#944: > Per rust-lang#71009, the ability to load target spec JSONs was stabilised accidentally. Within the team, we've always considered the format to be unstable and have changed it freely. This has been feasible as custom targets can only be used with core, like any other target, and so custom targets de-facto require nightly to be used (i.e. to build core manually or use Cargo's -Zbuild-std). > > Current build-std RFCs (rust-lang/rfcs#3873, rust-lang/rfcs#3874) propose a mechanism for building core on stable (at the request of Rust for Linux), which combined with a stable target-spec-json format, permit the current format to be used much more widely on stable toolchains. This would prevent us from improving the format - making it less tied to LLVM, switching to TOML, enabling keys in the spec to be stabilised individually, etc. > > De-stabilising the format gives us the opportunity to improve the format before it is too challenging to do so. Internal company toolchains and projects like Rust for Linux already use target-spec-json, but must use nightly at some point while doing so, so while it could be inconvenient for those users to destabilise this, it is hoped that an minimal alternative that we could choose to stabilise can be proposed relatively quickly.
Add a new Cargo configuration option,
build-std = "always|never", which will unconditionally rebuild standard library dependencies. The set of standard library dependencies can optionally be customised with a newbuild-std-cratesoption. It also describes how Cargo (or external tools) should build the standard library crates on stable (i.e., which flags to pass and features to enable).This proposal limits the ways the built standard library can be customised (such as by settings in the profile) and intends that the build standard library matches the prebuilt one (if available) as closely as possible.
This RFC is is part of the build-std project goal and a series of build-std RFCs:
build-std="always"(this RFC)build-std="compatible"(RFC not opened yet)build-std="match-profile"(RFC not opened yet)There is also a Zulip channel where you can ask questions about any of the build-std RFCs. This series of RFCs was drafted over many months with the help of stakeholders from many Rust project teams, we thank them for their help!
Rendered