Skip to content

Commit d744afe

Browse files
committed
fix(build-std): determine root crates by target spec std:bool
In #14183 Cargo starts bailing out if the `metadata.std` field in a target spec JSON is set to `false`. This is problematic because std for some targets are actually buildable even they've declared as std-unsupported. This patch removes the hard error, and instead determines the required root crates by the `metadata.std` field. That is to say, if a target is explicitly declared as `std: false`, `-Zbuild-std` will build `core` and `compiler-builtins` only, no `std` will be built. This patch doesn't change the behavior of `-Zbuild-std` with explicit crates set. For example `-Zbuild-std=std` will force building `std`. See Zulip discussion: https://rust-lang.zulipchat.com/#narrow/channel/246057-t-cargo/topic/help.20debugging.20a.20docs.2Ers.20issue.20with.20a.20new.20cargo.20error
1 parent 0802d22 commit d744afe

File tree

3 files changed

+126
-29
lines changed

3 files changed

+126
-29
lines changed

.github/workflows/main.yml

+2
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ jobs:
161161
- run: rustup update --no-self-update stable
162162
- run: rustup update --no-self-update ${{ matrix.rust }} && rustup default ${{ matrix.rust }}
163163
- run: rustup target add ${{ matrix.other }}
164+
- run: rustup target add aarch64-unknown-none # need this for build-std mock tests
165+
if: startsWith(matrix.rust, 'nightly')
164166
- run: rustup component add rustc-dev llvm-tools-preview rust-docs
165167
if: startsWith(matrix.rust, 'nightly')
166168
- run: sudo apt update -y && sudo apt install lldb gcc-multilib libsecret-1-0 libsecret-1-dev -y

src/cargo/core/compiler/standard_lib.rs

+58-23
Original file line numberDiff line numberDiff line change
@@ -116,31 +116,65 @@ pub fn generate_std_roots(
116116
profiles: &Profiles,
117117
target_data: &RustcTargetData<'_>,
118118
) -> CargoResult<HashMap<CompileKind, Vec<Unit>>> {
119-
let std_ids = std_crates(crates, Some(units))
120-
.iter()
121-
.map(|crate_name| std_resolve.query(crate_name))
122-
.collect::<CargoResult<Vec<PackageId>>>()?;
123-
// Convert PackageId to Package.
124-
let std_pkgs = package_set.get_many(std_ids)?;
119+
let (core_only, maybe_std): (Vec<&CompileKind>, Vec<_>) = kinds.iter().partition(|kind|
120+
// Only include targets that explicitly don't support std
121+
target_data.info(**kind).supports_std == Some(false));
122+
let std_pkgs = if maybe_std.is_empty() {
123+
None
124+
} else {
125+
let pkg_ids = std_crates(crates, Some(units))
126+
.iter()
127+
.map(|crate_name| std_resolve.query(crate_name))
128+
.collect::<CargoResult<Vec<PackageId>>>()?;
129+
Some(package_set.get_many(pkg_ids)?)
130+
};
131+
let core_pkgs = if core_only.is_empty() {
132+
None
133+
} else {
134+
let crates = if crates.is_empty() {
135+
&["core".to_string()]
136+
} else {
137+
crates
138+
};
139+
let pkg_ids = std_crates(crates, Some(units))
140+
.iter()
141+
.map(|crate_name| std_resolve.query(crate_name))
142+
.collect::<CargoResult<Vec<PackageId>>>()?;
143+
Some(package_set.get_many(pkg_ids)?)
144+
};
145+
125146
// Generate a map of Units for each kind requested.
126147
let mut ret = HashMap::new();
127-
gather_roots(
128-
&mut ret,
129-
&std_pkgs,
130-
std_features,
131-
kinds,
132-
interner,
133-
profiles,
134-
target_data,
135-
);
148+
if let Some(pkgs) = std_pkgs {
149+
gather_roots(
150+
&mut ret,
151+
&pkgs,
152+
std_features,
153+
&maybe_std,
154+
interner,
155+
profiles,
156+
target_data,
157+
);
158+
}
159+
if let Some(pkgs) = core_pkgs {
160+
gather_roots(
161+
&mut ret,
162+
&pkgs,
163+
std_features,
164+
&core_only,
165+
interner,
166+
profiles,
167+
target_data,
168+
);
169+
}
136170
Ok(ret)
137171
}
138172

139173
fn gather_roots(
140174
ret: &mut HashMap<CompileKind, Vec<Unit>>,
141175
pkgs: &[&Package],
142176
std_features: &ResolvedFeatures,
143-
kinds: &[CompileKind],
177+
kinds: &[&CompileKind],
144178
interner: &UnitInterner,
145179
profiles: &Profiles,
146180
target_data: &RustcTargetData<'_>,
@@ -157,25 +191,26 @@ fn gather_roots(
157191
let mode = CompileMode::Build;
158192
let features = std_features.activated_features(pkg.package_id(), FeaturesFor::NormalOrDev);
159193
for kind in kinds {
160-
let list = ret.entry(*kind).or_insert_with(Vec::new);
161-
let unit_for = UnitFor::new_normal(*kind);
194+
let kind = **kind;
195+
let list = ret.entry(kind).or_insert_with(Vec::new);
196+
let unit_for = UnitFor::new_normal(kind);
162197
let profile = profiles.get_profile(
163198
pkg.package_id(),
164199
/*is_member*/ false,
165200
/*is_local*/ false,
166201
unit_for,
167-
*kind,
202+
kind,
168203
);
169204
list.push(interner.intern(
170205
pkg,
171206
lib,
172207
profile,
173-
*kind,
208+
kind,
174209
mode,
175210
features.clone(),
176-
target_data.info(*kind).rustflags.clone(),
177-
target_data.info(*kind).rustdocflags.clone(),
178-
target_data.target_config(*kind).links_overrides.clone(),
211+
target_data.info(kind).rustflags.clone(),
212+
target_data.info(kind).rustdocflags.clone(),
213+
target_data.target_config(kind).links_overrides.clone(),
179214
/*is_std*/ true,
180215
/*dep_hash*/ 0,
181216
IsArtifact::No,

tests/testsuite/standard_lib.rs

+66-6
Original file line numberDiff line numberDiff line change
@@ -429,12 +429,72 @@ fn build_std_with_no_arg_for_core_only_target() {
429429
p.cargo("build -v")
430430
.arg("--target=aarch64-unknown-none")
431431
.build_std(&setup)
432-
.with_status(101)
433-
.with_stderr_data(str![[r#"
434-
...
435-
error[E0463]: can't find crate for `std`
436-
...
437-
"#]])
432+
.with_stderr_data(
433+
str![[r#"
434+
[UPDATING] `dummy-registry` index
435+
[DOWNLOADING] crates ...
436+
[DOWNLOADED] registry-dep-using-std v1.0.0 (registry `dummy-registry`)
437+
[DOWNLOADED] registry-dep-using-core v1.0.0 (registry `dummy-registry`)
438+
[DOWNLOADED] registry-dep-using-alloc v1.0.0 (registry `dummy-registry`)
439+
[COMPILING] compiler_builtins v0.1.0 ([..]/library/compiler_builtins)
440+
[COMPILING] core v0.1.0 ([..]/library/core)
441+
[COMPILING] foo v0.0.1 ([ROOT]/foo)
442+
[RUNNING] `[..] rustc --crate-name compiler_builtins [..]--target aarch64-unknown-none[..]`
443+
[RUNNING] `[..] rustc --crate-name core [..]--target aarch64-unknown-none[..]`
444+
[RUNNING] `[..] rustc --crate-name foo [..]--target aarch64-unknown-none[..]`
445+
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
446+
447+
"#]]
448+
.unordered(),
449+
)
450+
.run();
451+
452+
p.cargo("clean").run();
453+
454+
// Also work for a mix of std and core-only targets,
455+
// though not sure how common it is...
456+
//
457+
// Note that we don't download std dependencies for the second call
458+
// because `-Zbuild-std` downloads them all also when building for core only.
459+
p.cargo("build -v")
460+
.arg("--target=aarch64-unknown-none")
461+
.target_host()
462+
.build_std(&setup)
463+
.with_stderr_data(
464+
str![[r#"
465+
[UPDATING] `dummy-registry` index
466+
[COMPILING] core v0.1.0 ([..]/library/core)
467+
[COMPILING] dep_test v0.1.0 ([..]/dep_test)
468+
[COMPILING] compiler_builtins v0.1.0 ([..]/library/compiler_builtins)
469+
[COMPILING] proc_macro v0.1.0 ([..]/library/proc_macro)
470+
[COMPILING] panic_unwind v0.1.0 ([..]/library/panic_unwind)
471+
[COMPILING] rustc-std-workspace-core v1.9.0 ([..]/library/rustc-std-workspace-core)
472+
[COMPILING] foo v0.0.1 ([ROOT]/foo)
473+
[COMPILING] registry-dep-using-core v1.0.0
474+
[COMPILING] alloc v0.1.0 ([..]/library/alloc)
475+
[COMPILING] rustc-std-workspace-alloc v1.9.0 ([..]/library/rustc-std-workspace-alloc)
476+
[COMPILING] registry-dep-using-alloc v1.0.0
477+
[COMPILING] std v0.1.0 ([..]/library/std)
478+
[RUNNING] `[..]rustc --crate-name compiler_builtins [..]--target aarch64-unknown-none[..]`
479+
[RUNNING] `[..]rustc --crate-name core [..]--target aarch64-unknown-none[..]`
480+
[RUNNING] `[..]rustc --crate-name foo [..]--target aarch64-unknown-none[..]`
481+
[RUNNING] `[..]rustc --crate-name core [..]--target [HOST_TARGET][..]`
482+
[RUNNING] `[..]rustc --crate-name dep_test [..]--target [HOST_TARGET][..]`
483+
[RUNNING] `[..]rustc --crate-name proc_macro [..]--target [HOST_TARGET][..]`
484+
[RUNNING] `[..]rustc --crate-name panic_unwind [..]--target [HOST_TARGET][..]`
485+
[RUNNING] `[..]rustc --crate-name compiler_builtins [..]--target [HOST_TARGET][..]`
486+
[RUNNING] `[..]rustc --crate-name rustc_std_workspace_core [..]--target [HOST_TARGET][..]`
487+
[RUNNING] `[..]rustc --crate-name registry_dep_using_core [..]--target [HOST_TARGET][..]`
488+
[RUNNING] `[..]rustc --crate-name alloc [..]--target [HOST_TARGET][..]`
489+
[RUNNING] `[..]rustc --crate-name rustc_std_workspace_alloc [..]--target [HOST_TARGET][..]`
490+
[RUNNING] `[..]rustc --crate-name registry_dep_using_alloc [..]--target [HOST_TARGET][..]`
491+
[RUNNING] `[..]rustc --crate-name std [..]--target [HOST_TARGET][..]`
492+
[RUNNING] `[..]rustc --crate-name foo [..]--target [HOST_TARGET][..]`
493+
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
494+
495+
"#]]
496+
.unordered(),
497+
)
438498
.run();
439499
}
440500

0 commit comments

Comments
 (0)