Skip to content

Commit 30d11ce

Browse files
committed
refactor(build-std): defer std crates to build
Instead of altering the original `-Zbuild-std` arg value, this defers the timing of detereming which crate to build to when Cargo generates std root units.
1 parent e18b64f commit 30d11ce

File tree

3 files changed

+29
-55
lines changed

3 files changed

+29
-55
lines changed

src/cargo/core/compiler/standard_lib.rs

Lines changed: 26 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,54 +9,40 @@ use crate::core::resolver::HasDevUnits;
99
use crate::core::{PackageId, PackageSet, Resolve, Workspace};
1010
use crate::ops::{self, Packages};
1111
use crate::util::errors::CargoResult;
12-
use crate::GlobalContext;
12+
1313
use std::collections::{HashMap, HashSet};
1414
use std::path::PathBuf;
1515

1616
use super::BuildConfig;
1717

18-
/// Parse the `-Zbuild-std` flag.
19-
pub fn parse_unstable_flag(value: Option<&str>) -> Vec<String> {
18+
fn std_crates<'a>(crates: &'a [String], units: Option<&[Unit]>) -> HashSet<&'a str> {
19+
let mut crates = HashSet::from_iter(crates.iter().map(|s| s.as_str()));
2020
// This is a temporary hack until there is a more principled way to
2121
// declare dependencies in Cargo.toml.
22-
let value = value.unwrap_or("std");
23-
let mut crates: HashSet<&str> = value.split(',').collect();
22+
if crates.is_empty() {
23+
crates.insert("std");
24+
}
2425
if crates.contains("std") {
2526
crates.insert("core");
2627
crates.insert("alloc");
2728
crates.insert("proc_macro");
2829
crates.insert("panic_unwind");
2930
crates.insert("compiler_builtins");
30-
} else if crates.contains("core") {
31-
crates.insert("compiler_builtins");
32-
}
33-
crates.into_iter().map(|s| s.to_string()).collect()
34-
}
35-
36-
pub(crate) fn std_crates(gctx: &GlobalContext, units: Option<&[Unit]>) -> Option<Vec<String>> {
37-
let crates = gctx.cli_unstable().build_std.as_ref()?.clone();
38-
39-
// Only build libtest if it looks like it is needed.
40-
let mut crates = crates.clone();
41-
// If we know what units we're building, we can filter for libtest depending on the jobs.
42-
if let Some(units) = units {
43-
if units
44-
.iter()
45-
.any(|unit| unit.mode.is_rustc_test() && unit.target.harness())
46-
{
47-
// Only build libtest when libstd is built (libtest depends on libstd)
48-
if crates.iter().any(|c| c == "std") && !crates.iter().any(|c| c == "test") {
49-
crates.push("test".to_string());
31+
// Only build libtest if it looks like it is needed (libtest depends on libstd)
32+
// If we know what units we're building, we can filter for libtest depending on the jobs.
33+
if let Some(units) = units {
34+
if units
35+
.iter()
36+
.any(|unit| unit.mode.is_rustc_test() && unit.target.harness())
37+
{
38+
crates.insert("test");
5039
}
5140
}
52-
} else {
53-
// We don't know what jobs are going to be run, so download libtest just in case.
54-
if !crates.iter().any(|c| c == "test") {
55-
crates.push("test".to_string())
56-
}
41+
} else if crates.contains("core") {
42+
crates.insert("compiler_builtins");
5743
}
5844

59-
Some(crates)
45+
crates
6046
}
6147

6248
/// Resolve the standard library dependencies.
@@ -66,14 +52,16 @@ pub fn resolve_std<'gctx>(
6652
build_config: &BuildConfig,
6753
crates: &[String],
6854
) -> CargoResult<(PackageSet<'gctx>, Resolve, ResolvedFeatures)> {
55+
let crates = std_crates(crates, None);
56+
6957
if build_config.build_plan {
7058
ws.gctx()
7159
.shell()
7260
.warn("-Zbuild-std does not currently fully support --build-plan")?;
7361
}
7462

7563
// check that targets support building std
76-
if crates.contains(&"std".to_string()) {
64+
if crates.contains("std") {
7765
let unsupported_targets = target_data.get_unsupported_std_targets();
7866
if !unsupported_targets.is_empty() {
7967
anyhow::bail!(
@@ -95,7 +83,7 @@ pub fn resolve_std<'gctx>(
9583
std_ws.set_require_optional_deps(false);
9684
// `sysroot` is not in the default set because it is optional, but it needs
9785
// to be part of the resolve in case we do need it or `libtest`.
98-
let mut spec_pkgs = Vec::from(crates);
86+
let mut spec_pkgs: Vec<String> = crates.iter().map(|s| s.to_string()).collect();
9987
spec_pkgs.push("sysroot".to_string());
10088
let spec = Packages::Packages(spec_pkgs);
10189
let specs = spec.to_package_id_specs(&std_ws)?;
@@ -128,11 +116,13 @@ pub fn resolve_std<'gctx>(
128116
))
129117
}
130118

131-
/// Generate a list of root `Unit`s for the standard library.
119+
/// Generates a map of root units for the standard library for each kind requested.
132120
///
133-
/// The given slice of crate names is the root set.
121+
/// * `crates` is the arg value from `-Zbuild-std`.
122+
/// * `units` is the root units of the build.
134123
pub fn generate_std_roots(
135124
crates: &[String],
125+
units: &[Unit],
136126
std_resolve: &Resolve,
137127
std_features: &ResolvedFeatures,
138128
kinds: &[CompileKind],
@@ -141,8 +131,7 @@ pub fn generate_std_roots(
141131
profiles: &Profiles,
142132
target_data: &RustcTargetData<'_>,
143133
) -> CargoResult<HashMap<CompileKind, Vec<Unit>>> {
144-
// Generate the root Units for the standard library.
145-
let std_ids = crates
134+
let std_ids = std_crates(crates, Some(units))
146135
.iter()
147136
.map(|crate_name| std_resolve.query(crate_name))
148137
.collect::<CargoResult<Vec<PackageId>>>()?;

src/cargo/core/features.rs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,6 @@ unstable_cli_options!(
759759
avoid_dev_deps: bool = ("Avoid installing dev-dependencies if possible"),
760760
binary_dep_depinfo: bool = ("Track changes to dependency artifacts"),
761761
bindeps: bool = ("Allow Cargo packages to depend on bin, cdylib, and staticlib crates, and use the artifacts built by those crates"),
762-
#[serde(deserialize_with = "deserialize_build_std")]
763762
build_std: Option<Vec<String>> = ("Enable Cargo to compile the standard library itself as part of a crate graph compilation"),
764763
build_std_features: Option<Vec<String>> = ("Configure features enabled for the standard library itself when building the standard library"),
765764
cargo_lints: bool = ("Enable the `[lints.cargo]` table"),
@@ -873,19 +872,6 @@ const STABILIZED_LINTS: &str = "The `[lints]` table is now always available.";
873872
const STABILIZED_CHECK_CFG: &str =
874873
"Compile-time checking of conditional (a.k.a. `-Zcheck-cfg`) is now always enabled.";
875874

876-
fn deserialize_build_std<'de, D>(deserializer: D) -> Result<Option<Vec<String>>, D::Error>
877-
where
878-
D: serde::Deserializer<'de>,
879-
{
880-
let Some(crates) = <Option<Vec<String>>>::deserialize(deserializer)? else {
881-
return Ok(None);
882-
};
883-
let v = crates.join(",");
884-
Ok(Some(
885-
crate::core::compiler::standard_lib::parse_unstable_flag(Some(&v)),
886-
))
887-
}
888-
889875
#[derive(Debug, Copy, Clone, Default, Deserialize, Ord, PartialOrd, Eq, PartialEq)]
890876
#[serde(default)]
891877
pub struct GitFeatures {
@@ -1257,9 +1243,7 @@ impl CliUnstable {
12571243
"avoid-dev-deps" => self.avoid_dev_deps = parse_empty(k, v)?,
12581244
"binary-dep-depinfo" => self.binary_dep_depinfo = parse_empty(k, v)?,
12591245
"bindeps" => self.bindeps = parse_empty(k, v)?,
1260-
"build-std" => {
1261-
self.build_std = Some(crate::core::compiler::standard_lib::parse_unstable_flag(v))
1262-
}
1246+
"build-std" => self.build_std = Some(parse_list(v)),
12631247
"build-std-features" => self.build_std_features = Some(parse_list(v)),
12641248
"cargo-lints" => self.cargo_lints = parse_empty(k, v)?,
12651249
"codegen-backend" => self.codegen_backend = parse_empty(k, v)?,

src/cargo/ops/cargo_compile/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,10 +398,11 @@ pub fn create_bcx<'a, 'gctx>(
398398
Vec::new()
399399
};
400400

401-
let std_roots = if let Some(crates) = standard_lib::std_crates(gctx, Some(&units)) {
401+
let std_roots = if let Some(crates) = gctx.cli_unstable().build_std.as_ref() {
402402
let (std_resolve, std_features) = std_resolve_features.as_ref().unwrap();
403403
standard_lib::generate_std_roots(
404404
&crates,
405+
&units,
405406
std_resolve,
406407
std_features,
407408
&explicit_host_kinds,

0 commit comments

Comments
 (0)