From 283c4d43418f84cd5a1aca2dcbd712e35c56a6fa Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sun, 15 Dec 2024 13:51:39 -0500 Subject: [PATCH] fix(build-std): make Resolve completely align to what to build --- .../compiler/build_context/target_info.rs | 7 ++++ src/cargo/core/compiler/standard_lib.rs | 27 ++++++++++++---- src/cargo/ops/cargo_compile/mod.rs | 32 +++++++++---------- src/cargo/ops/cargo_fetch.rs | 10 ++++-- tests/build-std/main.rs | 5 --- 5 files changed, 51 insertions(+), 30 deletions(-) diff --git a/src/cargo/core/compiler/build_context/target_info.rs b/src/cargo/core/compiler/build_context/target_info.rs index e03c76d6bbf..6ddaea61b2a 100644 --- a/src/cargo/core/compiler/build_context/target_info.rs +++ b/src/cargo/core/compiler/build_context/target_info.rs @@ -619,6 +619,13 @@ impl TargetInfo { .iter() .any(|sup| sup.as_str() == split.as_str()) } + + /// Checks if a target support core only. + /// + /// If no explictly stated in target spec json, we treat it as "maybe support". + pub fn support_core_only(&self) -> bool { + matches!(self.supports_std, Some(false)) + } } /// Takes rustc output (using specialized command line args), and calculates the file prefix and diff --git a/src/cargo/core/compiler/standard_lib.rs b/src/cargo/core/compiler/standard_lib.rs index 5e9fe6af494..e2f3aa45537 100644 --- a/src/cargo/core/compiler/standard_lib.rs +++ b/src/cargo/core/compiler/standard_lib.rs @@ -44,10 +44,14 @@ fn std_crates<'a>(crates: &'a [String], default: &'static str, units: &[Unit]) - } /// Resolve the standard library dependencies. +/// +/// * `crates` is the arg value from `-Zbuild-std`. pub fn resolve_std<'gctx>( ws: &Workspace<'gctx>, target_data: &mut RustcTargetData<'gctx>, build_config: &BuildConfig, + crates: &[String], + kinds: &[CompileKind], ) -> CargoResult<(PackageSet<'gctx>, Resolve, ResolvedFeatures)> { if build_config.build_plan { ws.gctx() @@ -65,10 +69,19 @@ pub fn resolve_std<'gctx>( // `[dev-dependencies]`. No need for us to generate a `Resolve` which has // those included because we'll never use them anyway. std_ws.set_require_optional_deps(false); - // `sysroot` + the default feature set below should give us a good default - // Resolve, which includes `libtest` as well. - let specs = Packages::Packages(vec!["sysroot".into()]); - let specs = specs.to_package_id_specs(&std_ws)?; + let specs = { + // If there is any need std, resolve with it. + // This may need a UI overhaul if `build-std` wants to fully support multi-targets. + let core_only = kinds + .iter() + .all(|kind| target_data.info(*kind).support_core_only()); + let mut crates = std_crates(crates, if core_only { "core" } else { "std" }, &[]); + // `sysroot` is not in the default set because it is optional, but it needs + // to be part of the resolve in case we do need it or `libtest`. + crates.insert("sysroot"); + let specs = Packages::Packages(crates.into_iter().map(Into::into).collect()); + specs.to_package_id_specs(&std_ws)? + }; let features = match &gctx.cli_unstable().build_std_features { Some(list) => list.clone(), None => vec![ @@ -115,9 +128,9 @@ pub fn generate_std_roots( ) -> CargoResult>> { // Generate a map of Units for each kind requested. let mut ret = HashMap::new(); - let (core_only, maybe_std): (Vec<&CompileKind>, Vec<_>) = kinds.iter().partition(|kind| - // Only include targets that explicitly don't support std - target_data.info(**kind).supports_std == Some(false)); + let (core_only, maybe_std): (Vec<&CompileKind>, Vec<_>) = kinds + .iter() + .partition(|kind| target_data.info(**kind).support_core_only()); for (default_crate, kinds) in [("core", core_only), ("std", maybe_std)] { if kinds.is_empty() { continue; diff --git a/src/cargo/ops/cargo_compile/mod.rs b/src/cargo/ops/cargo_compile/mod.rs index c89c064c780..e650e313bab 100644 --- a/src/cargo/ops/cargo_compile/mod.rs +++ b/src/cargo/ops/cargo_compile/mod.rs @@ -289,15 +289,6 @@ pub fn create_bcx<'a, 'gctx>( resolved_features, } = resolve; - let std_resolve_features = if gctx.cli_unstable().build_std.is_some() { - let (std_package_set, std_resolve, std_features) = - standard_lib::resolve_std(ws, &mut target_data, &build_config)?; - pkg_set.add_set(std_package_set); - Some((std_resolve, std_features)) - } else { - None - }; - // Find the packages in the resolver that the user wants to build (those // passed in with `-p` or the defaults from the workspace), and convert // Vec to a Vec. @@ -398,21 +389,30 @@ pub fn create_bcx<'a, 'gctx>( Vec::new() }; - let std_roots = if let Some(crates) = gctx.cli_unstable().build_std.as_ref() { - let (std_resolve, std_features) = std_resolve_features.as_ref().unwrap(); - standard_lib::generate_std_roots( + let (std_roots, std_resolve_features) = if let Some(crates) = &gctx.cli_unstable().build_std { + let (std_package_set, std_resolve, std_features) = standard_lib::resolve_std( + ws, + &mut target_data, + &build_config, + crates, + &explicit_host_kinds, + )?; + pkg_set.add_set(std_package_set); + + let std_roots = standard_lib::generate_std_roots( &crates, &units, - std_resolve, - std_features, + &std_resolve, + &std_features, &explicit_host_kinds, &pkg_set, interner, &profiles, &target_data, - )? + )?; + (std_roots, Some((std_resolve, std_features))) } else { - Default::default() + (Default::default(), None) }; let mut unit_graph = build_unit_dependencies( diff --git a/src/cargo/ops/cargo_fetch.rs b/src/cargo/ops/cargo_fetch.rs index b1e596f6485..4ff89491d86 100644 --- a/src/cargo/ops/cargo_fetch.rs +++ b/src/cargo/ops/cargo_fetch.rs @@ -64,8 +64,14 @@ pub fn fetch<'a>( } // If -Zbuild-std was passed, download dependencies for the standard library. - if gctx.cli_unstable().build_std.is_some() { - let (std_package_set, _, _) = standard_lib::resolve_std(ws, &mut data, &build_config)?; + if let Some(crates) = &gctx.cli_unstable().build_std { + let (std_package_set, _, _) = standard_lib::resolve_std( + ws, + &mut data, + &build_config, + crates, + &build_config.requested_kinds, + )?; packages.add_set(std_package_set); } diff --git a/tests/build-std/main.rs b/tests/build-std/main.rs index c5c8a8fe816..f7eb4ec6e3b 100644 --- a/tests/build-std/main.rs +++ b/tests/build-std/main.rs @@ -413,10 +413,5 @@ fn test_panic_abort() { .build_std_arg("std,panic_abort") .env("RUSTFLAGS", "-C panic=abort") .arg("-Zbuild-std-features=panic_immediate_abort") - .with_status(101) - .with_stderr_data(str![[r#" -[ERROR] package ID specification `panic_unwind` did not match any packages - -"#]]) .run(); }