Repository navigation
Rollup of 6 pull requests - #164593
Rollup of 6 pull requests#164593
Conversation
But still keep the `-Zembed-metadata` variant for now, to make the migration easier.
We already have a fallback when the linker doesn't support `-static-pie` to use plain `-static` instead. However, it is also possible that the linker understands that option, but the C library doesn't have the necessary CRT objects. For example, `gcc` has known this option for a long time, but `glibc` doesn't support it for `powerpc` targets at all. We can detect this case in the link output for `-static` fallback too.
LLVM 24 causes the `align NN` to be the last thing on the line, so the trailing comma caused a failure to match.
…=petrochenkov Stabilize `-Zembed-metadata` Tracking issue: rust-lang#139165 This PR proposes to stabilize the `-Zembed-metadata` compiler flag, so that Cargo can start using `-Cembed-metadata=no` by default on the stable channel. The flag can be used to avoid duplicating the metadata of Rust crates within `.rlib` and `.rmeta` files. This can reduce the size of the `target` directory anywhere from 5% to 35% on real-world projects, depending on the chosen compilation profile ([1][kobzol-blog], [2][cargo-blog]). Additionally, `-Cembed-metadata=no` also removes the metadata out of Rust `dylib`s, and thus reduces their size. The plan is to stabilize this compiler flag so that Cargo can start using it on the stable channel. The stabilization plan thus has two parts: - Stabilize the `-Cembed-metadata` flag in `rustc` - Change Cargo to use `-Cembed-metadata=no` by default The Cargo team has prepared their side of the [stabilization report](rust-lang/cargo#17533). You can examine it to see the whole picture. ## What is being stabilized The `-Zembed-metadata` compiler flag. Note that `rustc` will still default to `-Cembed-metadata=yes`, as that is its original behavior since [Rust 1.16.0](https://blog.rust-lang.org/2017/03/16/Rust-1.16/#other-improvements). But it will now be possible to pass `-Cembed-metadata=no` on stable. ## Motivation When compiling Rust crates as libraries, Cargo uses pipelined compilation, which tells `rustc` (using `--emit=metadata`) to output an `.rmeta` file as soon as possible, so that Cargo can start follow-up `rustc` instances sooner and speed up the compilation process. This file contains the Rust-specific metadata of the compiled crate. However, after the compilation of the Rust crate finishes, the compiler will also write an `.rlib` file to disk, which contains both the compiled object code, but also the same metadata that is already contained in the `.rmeta` file. This means that after the compilation finishes, the metadata of each (non-leaf) compiled crate will be duplicated on disk. The metadata can be quite large, and it is not uncommon that it takes hundreds of megabytes for real-world projects. This duplication thus contributes to increasing the size of the `target` directory, which large size is one of the top 3 most pressing [challenges](https://blog.rust-lang.org/2026/03/02/2025-State-Of-Rust-Survey-results/#challenges-and-wishes-about-rust) that Rust users struggle with. The `-Cembed-metadata=no` flag removes this duplication (see [below](#What-does-the-flag-do) on how it works). Some size benchmark results can be found in ([1][kobzol-blog], [2][cargo-blog]). It can reach up to 35% size reduction on real-world projects in `release` mode, with the effect being smaller for `dev` builds (because incremental artifacts and debuginfo start to dominate the `target` directory size). A slight bonus is that we only write the metadata to disk once, thus resulting in less I/O. I haven't noticed any measurable effect (either positive or negative) on compile times though, at least on Linux. The main motivation is disk size, not compilation speed. ## What does the flag do When you pass `-Cembed-metadata=no`, `rustc` will not write the full metadata of the compiled crate into the emitted `.rlib` file. Instead, it will only write a ["metadata stub"](https://github.com/rust-lang/rust/blob/79ee8dc08073a0abf93d2b494ac5c1be11d4342e/compiler/rustc_metadata/src/rmeta/encoder.rs#L2552), which only contains the most basic information (name, target tuple, SVH). Note that this flag should usually be combined with `--emit=metadata` to write the metadata to a `.rmeta` file, otherwise no metadata would be generated at all. When loading crate dependencies passed via `--extern`, `rustc` will read the metadata of the passed `.rlib`. If it only contains a stub, it expects that you will also pass another `--extern` flag with a path to a `.rmeta` file with the full metadata. If you don't, you will be met with the following error: ``` error: only metadata stub found for `rlib` dependency `foo`. Please provide path to the corresponding .rmeta file with full metadata ``` Note that `rustc` will still default to the original behavior of embedding metadata, so build systems that wrap `rustc` will have to explicitly opt into using `-Cembed-metadata=no`, and at that point they will also have to start passing `--extern=<...>.rmeta` flags to `rustc`. That is what Cargo currently does if you use `nightly` or if you use the unstable `-Zembed-metadata=no` *Cargo* flag. In theory, we could relax the requirement to pass both paths to the `.rlib` and the `.rmeta` file for each direct dependency in the future, and let `rustc --extern=foo/bar.rlib` automatically attempt to load `--extern=foo/bar.rmeta` when the `.rmeta` file path is not passed explicitly. `.rlib` and `.rmeta` files produced using `-Cembed-metadata=no` and `-Cembed-metadata=yes` can be freely combined, and a downstream `rustc` invocation that consumes artifacts produced by `=no` does not need to itself receive the `=no` flag. ## Ecosystem impact The `-Zembed-metadata` flag has been used for the standard library that we ship since January 2026 (rust-lang#145343) and for the compiler itself and codegen backends (cg_clif and cg_gcc) since August 2026 (rust-lang#151061). The flag has also been used by Cargo by default on the `nightly` channel since the second half of August 2026. A blog post with a call for testing can be found [here](https://blog.rust-lang.org/inside-rust/2026/08/18/reducing-target-dir-size-on-nightly/). I'm not aware of any regressions or issues reported in relation to this, not is the Cargo team (AFAIK). There are some unresolved questions about backwards compability if Cargo starts passing `-Cembed-metadata=no` by default, but those are related strictly to Cargo, and not the compiler flag itself (because the compiler flag will remain opt-in). ## History The issue of duplicated metadata was originally noted back in 2015 (rust-lang#23366, rust-lang#29511), back then because of the metadata being duplicated in Rust `dylib`s. Since Cargo started using pipelined compilation by default, it became more acute, because the metadata of all compiled `.rlib` crate dependencies started being duplicated in the `target` directory. @bjorn3 proposed to add a compiler flag to split out the metadata into a separate file in rust-lang#57076. The implementation was attempted in rust-lang#93945 and later in rust-lang#120855, but there was non-trivial complexity due to Cargo integration. In 2025, I opened an [MCP](rust-lang/compiler-team#851) with the plan to implement this flag in two stages (first in rustc, and only then in Cargo), to reduce the implementation complexity, which was accepted. The implementation in `rustc` then happened in rust-lang#137535. Implementation history: - rust-lang#137535 (April 2025): Introduction of `-Zembed-metadata`, reviewed by @petrochenkov - rust-lang/cargo#15378 (May 2025): Initial integration in Cargo, reviewed by @epage - rust-lang#145343 (January 2026): Dogfood the flag for stdlib, reviewed by @bjorn3 - rust-lang#151061 (August 2026): Dogfood the flag for rustc and codegen backends, authored by @bjorn3 - rust-lang/cargo#17267 (August 2026): Enabled the `-Cembed-metadata=no` flag by default by Cargo on the `nightly` channel ## Unresolved questions/concerns ### Command-line length limit This is more related to the Cargo side of things, but I also wanted to mention it here, because there is a possible improvement we could do on the compiler side in the future. As noted [above](#What-does-the-flag-do), usage of `-Cembed-metadata=no` requires the build system/user to pass two `--extern` flags for each direct dependency of a given `rustc` invocation. This can increase the size of the executed command-line arguments, which can in edge cases start running into operating system limits. Recently, we saw something similar in action with the Cargo's new build dir layout stabilization, where Cargo suddenly started passing a lot more `-L` flags to `rustc`, which caused issues around CLI length limits and `PATH` env. var. length limits. Cargo can work around the CLI length limit by using response files (`rustc @args`), but not all downstream tools (such as `sccache`) support those fully (yet). Based on the experience with the new build dir layout, some work was done to improve this support in the ecosystem though, and to optimize the number of flags that Cargo passes to `rustc`. If this became a problem in practice, we could teach `rustc` to start implicitly assuming `--extern=foo.rmeta` when `--extern=foo.rlib` was passed. This would reduce the number of required `--extern` flags passed to the same count as with `-Cembed-metadata=yes` (or without using that flag at all). I think that we can always do this retroactively if needed without breaking backwards compatibility, so it does not have to block this stabilization. ### Landing this change Given that this compiler flag is expected to have tight integration with Cargo, and Cargo already uses it on the nightly channel by default, we have to be a bit careful about how we actually land the `-Zembed-metadata` => `-Cembed-metadata` change. Problem A: if we simply switched it from `-Z` to `-C` in `rust-lang/rust`, then nightly would break from the following day, because Cargo would be still attempting to pass the `-Z` flag, while `rustc` would already be expecting the `-C` variant of the flag. Problem B: furthermore, bootstrap currently unconditionally passes `-Zembed-metadata=no`, both to in-tree Cargo and to beta Cargo, so that also requires some attention. There are several options of how we could resolve this: 1. Conclude the nightly Cargo experiment, so that it will not pass `-Zembed-metadata=no` to `rustc` by default anymore. Then sync Cargo to `rust-lang/rust`, and only then merge this PR. This solves A. 2. Move Cargo from a git submodule to a (Josh) subtree, so that we can atomically change both Cargo and `rustc` to use `-C` instead of `-Z` (inside this PR), to avoid breaking nightly users. This solves A. - Even though I would like to do this migration anyway, I don't think that we need to tie it to this stabilization, as it can take some time before we resolve all concerns about the migration. 3. Do what 2. proposes, but without a subtree. That means that we have to: - Change to `-C` in Cargo - Change to `-C` in `rust-lang/rust` - Sync the Cargo change back to `rust-lang/rust` in the same day that we land the `rustc` change While this solves A, it might run into some staging issues in bootstrap, and it looks very complicated to pull off. 4. Teach `rustc` to accept both the `-Z` and the `-C` variant of the flag for some time. This solves both A and B, and also gives people who use `-Zembed-metadata` manually on `nightly` some breathing room to upgrade to the `-C` variant of the flag (but GitHub code search didn't find many usages of this flag, and this is normally an expected breakage for users of unstable compiler flags). I decided to go with 4, because the integration with Cargo is tight, and modifying bootstrap back and forth to support `-Z`/no flag /`-C` would be busy work. This solves both A and B and requires little implementation effort. ## Acknowledgments - @bjorn3 for coming up with the idea, providing a reference implementation and mentoring me to finish up the implementation - @petrochenkov for reviewing the compiler side of things - @epage and @weihanglo for reviewing the Cargo side of things [kobzol-blog]: https://kobzol.github.io/rust/rustc/2025/06/02/reduce-cargo-target-dir-size-with-z-no-embed-metadata.html#cargo-integration [cargo-blog]: https://blog.rust-lang.org/inside-rust/2026/08/18/reducing-target-dir-size-on-nightly/#how-much-does-it-help CC @bjorn3 @petrochenkov @weihanglo @epage r? petrochenkov @rustbot label +needs-fcp +T-compiler
Miri can now handle the actual apple thread parking implementation Thanks to rust-lang/miri#5428 r? @joboet
…leywiser Add a fallback for `-static-pie` missing CRT objects We already have a fallback when the linker doesn't support `-static-pie` to use plain `-static` instead. However, it is also possible that the linker understands that option, but the C library doesn't have the necessary CRT objects. For example, `gcc` has known this option for a long time, but `glibc` doesn't support it for `powerpc` targets at all. We can detect this case in the link output for `-static` fallback too. Fixes rust-lang#164448
Remove `rest` in `LintCheck` It makes LintCheck sizeof pointer smaller, I'm also working on other stuff related to lints and `rest` not being Copy made for a lot of Clone calls. It also felt less error prone, when comparing lints you'd have to check for `rest` everywhere to not mess up. r? @JonathanBrouwer
linux thread_atexit: fix use of __dso_handle
`__dso_handle` is declared as
```rust
unsafe extern "C" {
#[linkage = "extern_weak"]
static __dso_handle: *mut u8;
}
```
Due to how rustc encodes weak statics, this means that the value we see is a *pointer to* the actual `__dso_handle` value, stored in a separate static that rustc creates for each weakly linked symbol. So when we are passing `&raw const __dso_handle` to `__cxa_thread_atexit_impl`, that is complete nonsense.
This fixes the code to pass the actual address of the symbol to `__cxa_thread_atexit_impl`.
Cc @bjorn3 @joboet
…r=petrochenkov tests: drop trailing comma on a couple of checks LLVM 24 causes the `align NN` to be the last thing on the line, so the trailing comma caused a failure to match. @rustbot label llvm-main
This comment has been minimized.
This comment has been minimized.
Rollup of 6 pull requests try-job: dist-various-1 try-job: test-various try-job: test-x86_64-gnu-aux try-job: test-x86_64-msvc-1 try-job: test-aarch64-apple-1 try-job: test-aarch64-apple-2 try-job: test-x86_64-mingw-1 try-job: test-i686-msvc try-job: test-armhf-gnu try-job: test-x86_64-gnu-llvm-22-3
This comment has been minimized.
This comment has been minimized.
What is this?This is an experimental post-merge analysis report that shows differences in test outcomes between the merged PR and its parent PR.Comparing bd4c6cc (parent) -> 07ea2af (this PR) Test differencesShow 3 test diffs3 doctest diffs were found. These are ignored, as they are noisy. Test dashboardRun cargo run --manifest-path src/ci/citool/Cargo.toml -- \
test-dashboard 07ea2af746e09a0e9e3ac9b39ee866bd9bf702a2 --output-dir test-dashboardAnd then open Job duration changes
How to interpret the job duration changes?Job durations can vary a lot, based on the actual runner instance |
|
Finished benchmarking commit (07ea2af): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis perf run didn't have relevant results for this metric. Max RSS (memory usage)Results (primary -1.0%, secondary -0.7%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (secondary 0.8%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 488.943s -> 489.513s (0.12%) |
|
📌 Perf builds for each rolled up PR:
parent commit: bd4c6cc4ae In the case of a perf regression, run the following command with the SHAs of each PR you suspect might be the cause: |
Successful merges:
-Zembed-metadata#163436 (Stabilize-Zembed-metadata)-static-piemissing CRT objects #164451 (Add a fallback for-static-piemissing CRT objects)restinLintCheck#164539 (RemoverestinLintCheck)r? @ghost
Create a similar rollup