Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 4 additions & 2 deletions src/compiler/build_context/target_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,9 +574,10 @@ impl TargetInfo {
target_kind: &TargetKind,
target_triple: &str,
gctx: &GlobalContext,
rustc: &Rustc,
) -> CargoResult<(Vec<FileType>, Vec<CrateType>)> {
match mode {
CompileMode::Build => self.calc_rustc_outputs(target_kind, target_triple, gctx),
CompileMode::Build => self.calc_rustc_outputs(target_kind, target_triple, gctx, rustc),
CompileMode::Test => {
match self.file_types(&CrateType::Bin, FileFlavor::Normal, target_triple)? {
Some(fts) => Ok((fts, Vec::new())),
Expand All @@ -598,6 +599,7 @@ impl TargetInfo {
target_kind: &TargetKind,
target_triple: &str,
gctx: &GlobalContext,
rustc: &Rustc,
) -> CargoResult<(Vec<FileType>, Vec<CrateType>)> {
let mut unsupported = Vec::new();
let mut result = Vec::new();
Expand All @@ -619,7 +621,7 @@ impl TargetInfo {
}
}
if !result.is_empty() {
if !gctx.should_embed_metadata()
if !gctx.should_embed_metadata(rustc)
&& crate_types
.iter()
.any(|ct| ct.benefits_from_no_embed_metadata())
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/build_runner/compilation_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> {
&TargetKind::Bin,
bcx.target_data.short_name(&kind),
bcx.gctx,
bcx.rustc(),
)
.expect("target must support `bin`");

Expand Down Expand Up @@ -664,7 +665,7 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> {
let info = bcx.target_data.info(unit.kind);
let triple = bcx.target_data.short_name(&unit.kind);
let (file_types, unsupported) =
info.rustc_outputs(unit.mode, unit.target.kind(), triple, bcx.gctx)?;
info.rustc_outputs(unit.mode, unit.target.kind(), triple, bcx.gctx, bcx.rustc())?;
if file_types.is_empty() {
if !unsupported.is_empty() {
let unsupported_strs: Vec<_> = unsupported.iter().map(|ct| ct.as_str()).collect();
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/fingerprint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1676,7 +1676,7 @@ fn calculate_normal(
build_runner
.bcx
.gctx
.should_embed_metadata()
.should_embed_metadata(build_runner.bcx.rustc())
.not()
.hash(&mut config);

Expand Down
11 changes: 9 additions & 2 deletions src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1320,7 +1320,11 @@ fn build_base_args(

if unit.mode.is_check() {
cmd.arg("--emit=dep-info,metadata");
} else if !build_runner.bcx.gctx.should_embed_metadata() {
} else if !build_runner
.bcx
.gctx
.should_embed_metadata(build_runner.bcx.rustc())
{
// Nightly rustc supports the -Zembed-metadata=no flag, which tells it to avoid including
// full metadata in rlib/dylib artifacts, to save space on disk. In this case, metadata
// will only be stored in .rmeta files.
Expand Down Expand Up @@ -1814,7 +1818,10 @@ pub fn extern_args(
let mut result = Vec::new();
let deps = build_runner.unit_deps(unit);

let no_embed_metadata = !build_runner.bcx.gctx.should_embed_metadata();
let no_embed_metadata = !build_runner
.bcx
.gctx
.should_embed_metadata(build_runner.bcx.rustc());
let public_dependency_enabled = is_public_dependency_enabled(build_runner, unit);

// Closure to add one dependency to `result`.
Expand Down
15 changes: 13 additions & 2 deletions src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1269,8 +1269,19 @@ impl GlobalContext {
self.extra_verbose
}

pub fn should_embed_metadata(&self) -> bool {
self.cli_unstable().embed_metadata.unwrap_or(true)
pub fn should_embed_metadata(&self, rustc: &Rustc) -> bool {
match self.cli_unstable().embed_metadata {
Some(v) => v,
None => {
let cargo_nightly = matches!(
crate::version().release_channel.as_deref(),
Some("nightly" | "dev")
);
// Enable -Zembed-metadata=no by default if both cargo and rustc are nightly
let is_nightly = cargo_nightly && rustc.is_nightly;
!is_nightly
Comment on lines +1280 to +1282

@epage epage Jul 27, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should mirror the check done in #17258 (and maybe need to document this)

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My PR currently allows using the new default on stable via RUSTC_BOOTSTRAP. I can disable that, if you want.

But I think that the new build dir layout and this flag differs in how the nightly detection should work. The new build dir layout is purely a Cargo thing; regardless of which layout is used, it will woth with both stable and nightly rustc, the compiler doesn't really care. While the -Zembed-metadata flag requires the nightly compiler right now.

So my check only sets it by default when both Cargo and rustc are nightly. It could also just take a look at rustc, and not at Cargo, in theory.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like with #17258, this should not change the default with the presence of RUSTC_BOOTSTRAP. That is my main care about.

The rest is more styling (being consistent, being less invasive, etc).

Are there situations where a nightly Cargo is used with stable Rust that we care about? I've not checked what local; builds of Cargo consider itself (which I do run regularly).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could use the exact same approach as in #17258, and just enable -Zembed-metadata=no in nightly Cargo. But I cannot know the rustc version at the time the CLI options are created. So then I'd have to always check the rustc version even if the embed-metadata flag was set explicitly. So =no would essentially have to act as =no-if-nightly-rustc. Which is also valid, but it seems weird if you pass -Zembed-metadata=no explicitly and then the flag doesn't get used if the rustc isn't nightly.

Or I could use a fourth variant, EmbedMetadata::NoIfNightlyRustc, and use that on nightly be default. Though #17266 actually removes the enum and just turns it into Option<bool> to make it easier to load from the config.

Are there situations where a nightly Cargo is used with stable Rust that we care about? I've not checked what local; builds of Cargo consider itself (which I do run regularly).

I don't know about others, but when doing perf. benchmarks or various experiments with Cargo, I do often override RUSTC and use different cargo/rustc channels, it usually works fine. Local builds of Cargo should be dev, so the same as nightly.

}
}
}

pub fn network_allowed(&self) -> bool {
Expand Down
22 changes: 16 additions & 6 deletions src/ops/cargo_clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,14 @@ fn clean_specs(
] {
for (compile_kind, layout) in &layouts {
let triple = target_data.short_name(compile_kind);
let (file_types, _unsupported) = target_data
.info(*compile_kind)
.rustc_outputs(mode, target.kind(), triple, clean_ctx.gctx)?;
let (file_types, _unsupported) =
target_data.info(*compile_kind).rustc_outputs(
mode,
target.kind(),
triple,
clean_ctx.gctx,
&target_data.rustc,
)?;
let artifact_dir = layout
.artifact_dir()
.expect("artifact-dir was not locked during clean");
Expand Down Expand Up @@ -375,9 +380,14 @@ fn clean_specs(
] {
for (compile_kind, layout) in &layouts {
let triple = target_data.short_name(compile_kind);
let (file_types, _unsupported) = target_data
.info(*compile_kind)
.rustc_outputs(mode, target.kind(), triple, clean_ctx.gctx)?;
let (file_types, _unsupported) =
target_data.info(*compile_kind).rustc_outputs(
mode,
target.kind(),
triple,
clean_ctx.gctx,
&target_data.rustc,
)?;
let artifact_dir = layout
.artifact_dir()
.expect("artifact-dir was not locked during clean");
Expand Down
7 changes: 6 additions & 1 deletion src/util/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use tracing::{debug, info, warn};

use crate::compiler::apply_env_config;
use crate::util::interning::InternedString;
use crate::util::{CargoResult, GlobalContext, StableHasher};
use crate::util::{CargoResult, GlobalContext, StableHasher, VersionExt};

/// Information on the `rustc` executable
#[derive(Debug)]
Expand All @@ -32,6 +32,8 @@ pub struct Rustc {
pub host: InternedString,
/// The rustc full commit hash, this comes from `verbose_version`.
pub commit_hash: Option<String>,
/// Is the rustc on a nightly or a dev channel?
pub is_nightly: bool,
cache: Mutex<Cache>,
}

Expand Down Expand Up @@ -88,6 +90,8 @@ impl Rustc {
verbose_version
)
})?;
let is_nightly =
version.is_prerelease() && matches!(version.pre.as_str(), "dev" | "nightly");
let commit_hash = extract("commit-hash: ").ok().map(|hash| {
// Possible commit-hash values from rustc are SHA hex string and "unknown". See:
// * https://github.com/rust-lang/rust/blob/531cb83fc/src/bootstrap/src/utils/channel.rs#L73
Expand All @@ -114,6 +118,7 @@ impl Rustc {
version,
host,
commit_hash,
is_nightly,
cache: Mutex::new(cache),
})
}
Expand Down
4 changes: 1 addition & 3 deletions tests/testsuite/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6539,7 +6539,7 @@ fn embed_metadata_no_invalidate() {
)
.build();

p.cargo("build -Z embed-metadata=no")
p.cargo("build -Z embed-metadata=yes")
.masquerade_as_nightly_cargo(&["-Z embed-metadata"])
.with_stderr_data(str![[r#"
[LOCKING] 1 package to highest compatible version
Expand All @@ -6552,8 +6552,6 @@ fn embed_metadata_no_invalidate() {
p.cargo("build")
.masquerade_as_nightly_cargo(&["-Z embed-metadata"])
.with_stderr_data(str![[r#"
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
[COMPILING] foo v0.5.0 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s

"#]])
Expand Down
2 changes: 2 additions & 0 deletions tests/testsuite/build_script_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ fn rustc_bootstrap() {
// NOTE: uses RUSTC_BOOTSTRAP so it will be propagated to rustc
// (this matters when tests are being run with a beta or stable cargo)
.env("RUSTC_BOOTSTRAP", "1")
.arg("-Zembed-metadata=yes")
.with_stderr_data(str![[r#"
[COMPILING] has-dashes v0.0.1 ([ROOT]/foo)
[WARNING] has-dashes@0.0.1: cannot set `RUSTC_BOOTSTRAP=1` from build script of `has-dashes v0.0.1 ([ROOT]/foo)`.
Expand Down Expand Up @@ -187,6 +188,7 @@ fn rustc_bootstrap() {
// NOTE: uses RUSTC_BOOTSTRAP so it will be propagated to rustc
// (this matters when tests are being run with a beta or stable cargo)
.env("RUSTC_BOOTSTRAP", "1")
.arg("-Zembed-metadata=yes")
.with_stderr_data(str![[r#"
[COMPILING] foo v0.0.1 ([ROOT]/foo)
[WARNING] foo@0.0.1: cannot set `RUSTC_BOOTSTRAP=1` from build script of `foo v0.0.1 ([ROOT]/foo)`.
Expand Down