Skip to content

Commit 17413d4

Browse files
committed
Multi-target builds & libunwind expanded, various wording tightened
1 parent 04e538c commit 17413d4

File tree

4 files changed

+97
-57
lines changed

4 files changed

+97
-57
lines changed

text/0000-build-std/2-history.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,13 @@ categories:
174174
symbols provided by `libc`. compiler-builtins is also built with a large
175175
number of compilation units to force each function into a different unit.
176176

177+
['unwind'][wg-cargo-std-aware-29] will, by default, link to the system's
178+
version of libunwind. The feature `llvm-libunwind` or certain compiler flags
179+
such as `-Clink-self-contained` or `-Ctarget-feature=+crt-static` may cause
180+
Rust to statically link to the in-tree version of `libunwind`, which is built
181+
by bootstrap. Previously, this used to be built by `unwind`'s `build.rs`
182+
file.
183+
177184
[Sanitizers][wg-cargo-std-aware#17], when enabled, require a sanitizer
178185
runtime to be present. These are currently built by bootstrap and part of
179186
LLVM.

text/0000-build-std/4-stage-1a.md

Lines changed: 74 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ useful for users of tier three targets.
4343
> as is feasible.
4444
4545
Alongside `build-std`, a `build-std-crate` key will be introduced
46-
([?][rationale-build-std-crate]), which can be used to specify which crate from
46+
([?][rationale-build-std-crate]), which can be used to specify which "level" of
4747
the standard library is to be built. Only "core", "alloc" and "std" are valid
4848
values for `build-std-crate`.
4949

@@ -57,6 +57,9 @@ will not be used unless explicitly set and the crate graph's dependencies on the
5757
standard library will determine which crates are built instead. Otherwise,
5858
`build-std-crate` will default to "std".
5959

60+
If `std` is to be built and Cargo is building a test using the default test
61+
harness then Cargo will also build the `test` crate.
62+
6063
> [!NOTE]
6164
>
6265
> Inspired by the concept of [opaque dependencies][Opaque dependencies], the
@@ -71,21 +74,20 @@ standard library will determine which crates are built instead. Otherwise,
7174
> the dependencies of the `core`, `alloc` or `std` standard library crates
7275
> individually (via profile overrides, for example).
7376
>
74-
> - The profiles defined by the standard library will be used.
77+
> - The profile defined by the standard library will be used.
7578
>
7679
> Cargo will resolves the dependencies of opaque dependencies, such as the
77-
> standard library, separately in their own workspaces. The "roots" of such a
78-
> resolve are defined as the unified set of packages that any crate in the
79-
> dependency graph has a explicit dependency on and those which Cargo infers a
80-
> direct dependency on. A dependency on the roots are added to all crates in the
81-
> "parent" resolve.
80+
> standard library, separately in their own workspaces. The root of such a
81+
> resolve will be the crate specified in `build-std-crates`, or, if stage 1b is
82+
> implemented, the unified set of packages that any crate in the dependency
83+
> a direct dependency on. A dependency on the relevant roots are added to all
84+
> crates in the "parent" resolve.
8285
>
8386
> Regardless of which standard library crates are being built, Cargo will build
8487
> the `sysroot` crate of the standard library workspace. `alloc` and `std` will
8588
> be optional dependencies of the `sysroot` crate which will be enabled when the
86-
> user has requested them. The sysroot always depends on the `proc_macro` and
87-
> `test` crates. Panic runtimes are dependencies of `std` and will be enabled
88-
> depending on the features that Cargo passes to `std` (see
89+
> user has requested them. Panic runtimes are dependencies of `std` and will be
90+
> enabled depending on the features that Cargo passes to `std` (see
8991
> [*Panic strategies*][panic-strategies]).
9092
>
9193
> rustc loads panic runtimes in a different way to most dependencies, and
@@ -96,13 +98,14 @@ standard library will determine which crates are built instead. Otherwise,
9698
>
9799
> The standard library will always be a non-incremental build
98100
> ([?][rationale-incremental]), with no `depinfo` produced, and only a `rlib`
99-
> produced (no `dylib`) ([?][rationale-no-dylib]). It will be built into the
100-
> `target` directory of the crate or workspace like any other dependency.
101+
> produced (no `dylib`) ([?][rationale-no-dylib]). It will be built in Cargo's
102+
> "target" directory of the crate or workspace like any other dependency.
101103
102104
The host pre-built standard library will always be used for procedural macros
103-
and build scripts ([?][rationale-sysroot-for-host-deps]). Artifact dependencies
104-
use the same standard library as the rest of the crate (pre-built or
105-
newly-built, as appropriate).
105+
and build scripts ([?][rationale-sysroot-for-host-deps]). Multi-target projects
106+
(resulting from the "target" field in artifact dependencies or the use of
107+
`per-pkg-target` fields) may result in the standard library being built multiple
108+
times - once for each target in the project.
106109

107110
*See the following sections for rationale/alternatives:*
108111

@@ -127,10 +130,10 @@ newly-built, as appropriate).
127130
## Interactions with `#![no_std]`
128131
[interactions-with-no_std]: #interactions-with-no_std
129132

130-
Behaviour of crates using `#![no_std]` will change even if the standard library
131-
is rebuilt and passed via `--extern` to rustc. Due to `#![no_std]`, rustc will
132-
not automatically attempt to load std, but if the user writes `extern crate std`
133-
then the rebuilt std will be found.
133+
Behaviour of crates using `#![no_std]` will not change whether or not `std` is
134+
rebuilt and passed via `--extern` to rustc, and `#![no_std]` will still be
135+
required in order for `rustc` to not attempt to load `std` and add it to the
136+
extern prelude.
134137

135138
*See the following sections for rationale/alternatives:*
136139

@@ -198,8 +201,9 @@ explicit and implicit standard library dependencies.
198201
When it is necessary to build the standard library, Cargo will look for sources
199202
in a fixed location in the sysroot ([?][rationale-custom-src-path]):
200203
`lib/rustlib/src`. rustup's `rust-src` component downloads standard library
201-
sources to this location. If the sources are not found, Cargo will emit an error
202-
and recommend the user download `rust-src` if using rustup.
204+
sources to this location and will be made a default component. If the sources
205+
are not found, Cargo will emit an error and recommend the user download
206+
`rust-src` if using rustup.
203207

204208
`rust-src` will contain the sources for the standard library crates as well as
205209
its vendored dependencies ([?][rationale-vendoring]). As a consequence sources
@@ -217,12 +221,6 @@ of standard library dependencies will not need be fetched from crates.io.
217221
- [*Why vendor standard library dependencies?*][rationale-vendoring]
218222
- [*Why not check if `rust-src` has been modified?*][rationale-src-modifications]
219223

220-
### `libunwind`
221-
[libunwind]: #libunwind
222-
223-
`libunwind`'s sources are included in the `rust-src` component so that they can
224-
be used as part of the standard library build on targets which require it.
225-
226224
## Panic strategies
227225
[panic-strategies]: #panic-strategies
228226

@@ -261,6 +259,18 @@ In line with Cargo's stance on not parsing the `RUSTFLAGS` environment variable,
261259
it will not be checked for compilation flags that would require additional
262260
crates to be built for compilation to succeed.
263261

262+
> [!NOTE]
263+
>
264+
> This RFC does not propose building `libunwind` locally as `unwind`'s build
265+
> script [used to do][rust#84124]. The `unwind` crate usually links to the
266+
> system's `libunwind`, in which case any target modifiers used should be set
267+
> correctly to match compilation flags to match this artifact. Certain flags
268+
> such as `-Clink-self-contained=yes` may cause `rustc` to find `libunwind` in
269+
> the sysroot, in which case any set target modifiers may break linking.
270+
>
271+
> This could be treated similarly to the `compiler_builtins` manual `c` feature
272+
> in the future.
273+
264274
*See the following sections for future possibilities:*
265275

266276
- [*Avoid building `panic_unwind` unnecessarily*][future-panic_unwind]
@@ -284,7 +294,7 @@ A handful of targets require linking against special object files, such as
284294
`windows-gnu`, `linux-musl` and `wasi` targets. For example, `linux-musl`
285295
targets require `crt1.o`, `crti.o`, `crtn.o`, etc.
286296

287-
Since [rust#76185]/[compiler-team#343], the compiler has a stable
297+
Since [rust#76158]/[compiler-team#343], the compiler has a stable
288298
`-Clink-self-contained` flag which will look for special object files in
289299
expected locations, typically populated by the `rust-std` components. Its
290300
behaviour can be forced by `-Clink-self-contained=true`, but is force-enabled
@@ -313,7 +323,8 @@ missing special object files.
313323
[compiler-builtins]: #compiler-builtins
314324

315325
`compiler-builtins` is always built with `-Ccodegen-units=10000` to force each
316-
intrinsic into its own object file to avoid symbol clashes with libgcc.
326+
intrinsic into its own object file to avoid symbol clashes with libgcc. This is
327+
currently enforced with a profile override in the standard library's workspace.
317328

318329
rustc will automatically use a large number of codegen units for the
319330
`compiler-builtins` crate, unless manually specified using the `-Ccodegen-units`
@@ -352,14 +363,15 @@ It will not be enabled by default because it is possible that the target
352363
platform does not have a suitable C compiler available. The user being able to
353364
enable this manually will be enabled through work on features (see
354365
[*Allow enabling/disabling features with build-std*][future-features] from Stage
355-
1b).
366+
1b). This will require the user to manually configure `CFLAGS` to ensure that
367+
the c components will link with Rust code.
356368

357369
## Caching
358370
[caching]: #caching
359371

360372
Standard library artifacts built by build-std will not be shared between crates
361-
or workspaces, as they only exist in the `target` directory of a specific crate
362-
or workspace ([?][rationale-caching]).
373+
or workspaces, as they only exist in Cargo's target directory for a specific
374+
crate or workspace ([?][rationale-caching]).
363375

364376
*See the following sections for rationale/alternatives:*
365377

@@ -511,7 +523,7 @@ There are various alternatives to putting `build-std` in the Cargo configuration
511523

512524
2. build-std could be enabled or disabled in the `Cargo.toml`. However, under
513525
which conditions the standard library is rebuilt is better determined by the
514-
user of Cargo, rather than the project being built.
526+
user of Cargo, rather than the package being built.
515527

516528
A user may want to never rebuild the standard library so as to avoid
517529
invalidating the guarantees of their qualified toolchain, or may want to
@@ -672,9 +684,9 @@ which further limits potential use cases to those without `target-modifiers`.
672684
[rationale-replace-no_std]: #why-not-replace-no_std-as-the-source-of-truth-for-whether-a-crate-depends-on-std
673685

674686
Crates can currently use the crate attribute `#![no_std]` to indicate a lack of
675-
dependency on `std`. With `Cargo.toml` being used to express a dependency on the
676-
standard library (or lack thereof), it is unintuitive for there to be two
677-
sources-of-truth for this information.
687+
dependency on `std`. With Cargo being used to express a dependency (or lack
688+
thereof) on the standard library (and further so in [stage1b]) it is unintuitive
689+
for there to be two sources-of-truth for this information.
678690

679691
`#![no_std]` serves two purposes - it stops the compiler from loading `std` from
680692
the sysroot and adding `extern crate std`, and it prevents the user from
@@ -757,14 +769,17 @@ providing an empty path.
757769
### Why use `noprelude` with `--extern`?
758770
[rationale-noprelude-with-extern]: #why-use-noprelude-with---extern
759771

760-
The `noprelude` modifier for `--extern` is necessary for use of the `--extern`
761-
flag to be equivalent to using a modified sysroot.
772+
Rustc has logic specific to the standard library that decides when to add those
773+
crates to the extern prelude which will not be changed as part of this RFC.
774+
Adding The `noprelude` modifier for `--extern` is necessary for use of the
775+
`--extern` flag to be equivalent to loading from a sysroot.
762776

763777
Without `noprelude`, rustc implicitly inserts a `extern crate $name` when using
764778
`--extern`. As a consequence, if a newly-built `alloc` were passed using
765-
`--extern alloc=alloc.rlib` then `extern crate alloc` would not be required, but
766-
it would be if the pre-built `alloc` could be used. This difference in how a
767-
crate is made available to rustc should not be observable to the user.
779+
`--extern alloc=alloc.rlib` then `extern crate alloc` would not be required to
780+
use the locall-built `alloc`, but it would be to use the pre-built `alloc`. This
781+
difference in how a crate is made available to rustc should not be observable to
782+
the user.
768783

769784
[*Preventing implicit sysroot dependencies*][preventing-implicit-sysroot-dependencies]
770785

@@ -832,19 +847,23 @@ included.
832847
[rationale-implied-bootstrap]: #why-allow-building-from-the-sysroot-with-implied-rustc_bootstrap
833848

834849
Cargo needs to be able to build the standard library crates, which inherently
835-
require a nightly toolchain. It could set `RUSTC_BOOTSTRAP` internally to do
836-
this with a stable toolchain, however this is a shared requirement with other
837-
build systems that wish to build an unmodified standard library and want to work
838-
on stable toolchains.
839-
840-
For example, Rust's project goal to enable Rust for Linux to build using only a
841-
stable toolchain would require that it be possible to build `core` without
842-
nightly.
850+
require a nightly toolchain. This is a shared requirement with other build
851+
systems that wish to build an unmodified standard library and want to work
852+
on stable toolchains. For example, Rust's project goal to enable Rust for Linux
853+
to build using only a stable toolchain would require that it be possible to
854+
build `core` without nightly.
855+
856+
Cargo could continue to set `RUSTC_BOOTSTRAP` internally when building standard
857+
library crates with a stable toolchain, but the Rust project
858+
[does not wish to encourage][rustc-bootstrap-docs] widespread usage of this
859+
"escape-hatch" where possible. Allowing crate sources in the sysroot to use
860+
nightly features is a compromise and fits into the model of the sysroot being
861+
unique to that version of the toolchain.
843862

844863
It is not sufficient for rustc to special-case the `core`, `alloc` and `std`
845-
crate names as when being built as part of the standard library, dependencies of
846-
the standard library also use unstable features and so these crate would also
847-
need such special-casing, which is not practical.
864+
crate names as when being built as part of the standard library dependencies of
865+
the standard library also use unstable features. These crates would also need
866+
such special-casing, which is not practical.
848867

849868
[*Building the standard library on a stable toolchain*][building-the-standard-library-on-a-stable-toolchain]
850869

@@ -964,11 +983,13 @@ produced by build-std.
964983

965984
[compiler-builtins#411]: https://github.com/rust-lang/compiler-builtins/pull/411
966985
[compiler-team#343]: https://github.com/rust-lang/compiler-team/issues/343
967-
[rust#76185]: https://github.com/rust-lang/rust/pull/76185
986+
[rust#76158]: https://github.com/rust-lang/rust/pull/76158
968987
[rust#71009]: https://github.com/rust-lang/rust/pull/71009
988+
[rust#84124]: https://github.com/rust-lang/rust/pull/84124
969989
[rust#135395]: https://github.com/rust-lang/rust/pull/135395
970990

971991
[std-build.rs]: https://github.com/rust-lang/rust/blob/f315e6145802e091ff9fceab6db627a4b4ec2b86/library/std/build.rs#L17
992+
[rustc-bootstrap-docs]: https://doc.rust-lang.org/nightly/unstable-book/compiler-environment-variables/RUSTC_BOOTSTRAP.html#stability-policy
972993

973994
[cargo-add]: https://doc.rust-lang.org/cargo/commands/cargo-add.html
974995
[cargo-bench]: https://doc.rust-lang.org/cargo/commands/cargo-bench.html

text/0000-build-std/5-stage-1b.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,10 +328,10 @@ and cannot otherwise be found in the registry.
328328
>
329329
> The keys `req`, `registry` and `package` from `deps` are not required per the
330330
> limitations on builtin dependencies.
331-
>
331+
>
332332
> The key is optional and its default value will be the implicit builtin
333333
> dependencies:
334-
>
334+
>
335335
> ```json
336336
> "builtin_deps" : [
337337
> {
@@ -679,7 +679,7 @@ circumstance, then they would be located in a `-L dependency=` directory, which
679679
rustc would not search when loading a crate from `extern crate`.
680680
681681
> [!NOTE]
682-
>
682+
>
683683
> `alloc` and `core` must always be passed with `--extern`.
684684
685685
↩ [*Proposal*][proposal]

text/0000-build-std/6-stage-2.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@ As with the "always" option, the exact crates from the standard library to be
6161
built are determined by the `build-std-crate` option or explicit dependencies on
6262
the standard library if [*Stage 1b*][stage1b] was implemented.
6363
64+
Multi-target projects (resulting from the "target" field in artifact
65+
dependencies or the use of `per-pkg-target` fields) results in the decision to
66+
rebuild the standard library being made multiple times - once for each target in
67+
the project.
68+
69+
> [!NOTE]
70+
>
71+
> Because Cargo does not have per-target profiles nor a way to change the
72+
> standard library's profile at this stage the only way to configure the
73+
> standard library differently for different targets is with the use of the
74+
> `[target]` sections in the Cargo config.
75+
6476
*See the following sections for rationale/alternatives:*
6577
6678
- [*Why default to "compatible"?*][rationale-default]
@@ -143,7 +155,7 @@ It could be named "target-modifiers" or "automatic".
143155
## What should the interface to rustc compatibility checking be?
144156
[unresolved-rustc-compat-interface]: #what-should-the-interface-to-rustc-compatibility-checking-be
145157
146-
Should it an `--emit` flag? a `--print` flag?
158+
Should it be an `--emit` flag? A `--print` flag?
147159
148160
↩ [*Proposal*][proposal]
149161

0 commit comments

Comments
 (0)