From e9dd3066ad9ea6b1a7eb263b291161a5a1f7acb5 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 23 Sep 2019 10:04:51 -0700 Subject: [PATCH 1/8] Change build-std to use --sysroot. --- src/cargo/core/compiler/context/mod.rs | 7 ++- src/cargo/core/compiler/job_queue.rs | 7 ++- src/cargo/core/compiler/layout.rs | 49 ++++++++++++++++---- src/cargo/core/compiler/mod.rs | 22 ++++++++- src/cargo/core/compiler/standard_lib.rs | 46 ++++++++++++++++-- src/cargo/core/compiler/unit.rs | 4 ++ src/cargo/core/compiler/unit_dependencies.rs | 2 +- src/cargo/ops/cargo_clean.rs | 7 ++- src/cargo/ops/cargo_compile.rs | 11 ++++- 9 files changed, 131 insertions(+), 24 deletions(-) diff --git a/src/cargo/core/compiler/context/mod.rs b/src/cargo/core/compiler/context/mod.rs index db5ea9eca17..e6d9bd5d33b 100644 --- a/src/cargo/core/compiler/context/mod.rs +++ b/src/cargo/core/compiler/context/mod.rs @@ -18,6 +18,7 @@ use super::custom_build::{self, BuildDeps, BuildScriptOutputs, BuildScripts}; use super::fingerprint::Fingerprint; use super::job_queue::JobQueue; use super::layout::Layout; +use super::standard_lib; use super::unit_dependencies::{UnitDep, UnitGraph}; use super::{BuildContext, Compilation, CompileMode, Executor, FileFlavor, Kind}; @@ -304,7 +305,11 @@ impl<'a, 'cfg> Context<'a, 'cfg> { }; let host_layout = Layout::new(self.bcx.ws, None, dest)?; let target_layout = match self.bcx.build_config.requested_target.as_ref() { - Some(target) => Some(Layout::new(self.bcx.ws, Some(target), dest)?), + Some(target) => { + let layout = Layout::new(self.bcx.ws, Some(target), dest)?; + standard_lib::prepare_sysroot(&layout)?; + Some(layout) + } None => None, }; self.primary_packages diff --git a/src/cargo/core/compiler/job_queue.rs b/src/cargo/core/compiler/job_queue.rs index 9a3019abf1e..2d324c2a238 100644 --- a/src/cargo/core/compiler/job_queue.rs +++ b/src/cargo/core/compiler/job_queue.rs @@ -17,6 +17,7 @@ use super::job::{ Freshness::{self, Dirty, Fresh}, Job, }; +use super::standard_lib; use super::timings::Timings; use super::{BuildContext, BuildPlan, CompileMode, Context, Unit}; use crate::core::{PackageId, TargetKind}; @@ -607,7 +608,7 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> { id: u32, unit: &Unit<'a>, artifact: Artifact, - cx: &mut Context<'_, '_>, + cx: &mut Context<'a, '_>, ) -> CargoResult<()> { if unit.mode.is_run_custom_build() && cx.bcx.show_warnings(unit.pkg.package_id()) { self.emit_warnings(None, unit, cx)?; @@ -617,6 +618,10 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> { Artifact::All => self.timings.unit_finished(id, unlocked), Artifact::Metadata => self.timings.unit_rmeta_finished(id, unlocked), } + if unit.is_std && unit.kind == super::Kind::Target && !cx.bcx.build_config.build_plan { + let rmeta = artifact == Artifact::Metadata; + standard_lib::add_sysroot_artifact(cx, unit, rmeta)?; + } Ok(()) } diff --git a/src/cargo/core/compiler/layout.rs b/src/cargo/core/compiler/layout.rs index 3d5580b770a..0e192e20dc6 100644 --- a/src/cargo/core/compiler/layout.rs +++ b/src/cargo/core/compiler/layout.rs @@ -116,6 +116,10 @@ pub struct Layout { examples: PathBuf, /// The directory for rustdoc output: `$root/doc` doc: PathBuf, + /// The local sysroot for the build-std feature. + sysroot: Option, + /// The "lib" directory within `sysroot`. + sysroot_libdir: Option, /// The lockfile for a build (`.cargo-lock`). Will be unlocked when this /// struct is `drop`ped. _lock: FileLock, @@ -139,18 +143,21 @@ impl Layout { // Flexible target specifications often point at json files, so interpret // the target triple as a Path and then just use the file stem as the // component for the directory name in that case. - if let Some(triple) = triple { - let triple = Path::new(triple); - if triple.extension().and_then(|s| s.to_str()) == Some("json") { - root.push( - triple - .file_stem() + let triple_path = if let Some(s) = triple { + let p = Path::new(s); + let tp = if p.extension().and_then(|s| s.to_str()) == Some("json") { + Path::new( + p.file_stem() .ok_or_else(|| failure::format_err!("invalid target"))?, - ); + ) } else { - root.push(triple); - } - } + p + }; + root.push(tp); + Some(tp) + } else { + None + }; let dest = root.join(dest); // If the root directory doesn't already exist go ahead and create it // here. Use this opportunity to exclude it from backups as well if the @@ -167,6 +174,16 @@ impl Layout { let root = root.into_path_unlocked(); let dest = dest.into_path_unlocked(); + // Compute the sysroot path for the build-std feature. + let build_std = ws.config().cli_unstable().build_std.as_ref(); + let (sysroot, sysroot_libdir) = if let Some(tp) = build_std.and(triple_path) { + let sysroot = dest.join(".sysroot"); + let sysroot_libdir = sysroot.join("lib").join("rustlib").join(tp).join("lib"); + (Some(sysroot), Some(sysroot_libdir)) + } else { + (None, None) + }; + Ok(Layout { deps: dest.join("deps"), build: dest.join("build"), @@ -176,6 +193,8 @@ impl Layout { doc: root.join("doc"), root, dest, + sysroot, + sysroot_libdir, _lock: lock, }) } @@ -223,6 +242,16 @@ impl Layout { pub fn build(&self) -> &Path { &self.build } + /// The local sysroot for the build-std feature. + /// + /// Returns None if build-std is not enabled or this is the Host layout. + pub fn sysroot(&self) -> Option<&Path> { + self.sysroot.as_ref().map(|p| p.as_ref()) + } + /// The "lib" directory within `sysroot`. + pub fn sysroot_libdir(&self) -> Option<&Path> { + self.sysroot_libdir.as_ref().map(|p| p.as_ref()) + } } #[cfg(not(target_os = "macos"))] diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 1dd9c9e48ce..44bcc0afdf1 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -50,7 +50,7 @@ use crate::util::paths; use crate::util::{self, machine_message, ProcessBuilder}; use crate::util::{internal, join_paths, profile}; -/// Indicates whether an object is for the host architcture or the target architecture. +/// Indicates whether an object is for the host architecture or the target architecture. /// /// These will be the same unless cross-compiling. #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy, PartialOrd, Ord, Serialize)] @@ -915,6 +915,16 @@ fn build_base_args<'a, 'cfg>( let dir = cx.files().layout(unit.kind).incremental().as_os_str(); opt(cmd, "-C", "incremental=", Some(dir)); } + + if unit.is_std { + // -Zforce-unstable-if-unmarked prevents the accidental use of + // unstable crates within the sysroot (such as "extern crate libc" or + // any non-public crate in the sysroot). + // + // RUSTC_BOOTSTRAP allows unstable features on stable. + cmd.arg("-Zforce-unstable-if-unmarked") + .env("RUSTC_BOOTSTRAP", "1"); + } Ok(()) } @@ -968,7 +978,17 @@ fn build_deps_args<'a, 'cfg>( let mut unstable_opts = false; + if let Some(sysroot) = cx.files().layout(Kind::Target).sysroot() { + if unit.kind == Kind::Target { + cmd.arg("--sysroot").arg(sysroot); + } + } + for dep in deps { + if !unit.is_std && dep.unit.is_std { + // Dependency to sysroot crate uses --sysroot. + continue; + } if dep.unit.mode.is_run_custom_build() { cmd.env("OUT_DIR", &cx.files().build_script_out_dir(&dep.unit)); } diff --git a/src/cargo/core/compiler/standard_lib.rs b/src/cargo/core/compiler/standard_lib.rs index a6fced9cc1b..88a8c07af94 100644 --- a/src/cargo/core/compiler/standard_lib.rs +++ b/src/cargo/core/compiler/standard_lib.rs @@ -1,11 +1,13 @@ //! Code for building the standard library. -use crate::core::compiler::{BuildContext, CompileMode, Kind, Unit}; +use super::layout::Layout; +use crate::core::compiler::{BuildContext, CompileMode, Context, FileFlavor, Kind, Unit}; use crate::core::profiles::UnitFor; use crate::core::resolver::ResolveOpts; use crate::core::{Dependency, PackageId, PackageSet, Resolve, SourceId, Workspace}; use crate::ops::{self, Packages}; use crate::util::errors::CargoResult; +use crate::util::paths; use std::collections::{HashMap, HashSet}; use std::env; use std::path::PathBuf; @@ -141,9 +143,15 @@ pub fn generate_std_roots<'a>( bcx.build_config.release, ); let features = std_resolve.features_sorted(pkg.package_id()); - Ok(bcx - .units - .intern(pkg, lib, profile, Kind::Target, mode, features)) + Ok(bcx.units.intern( + pkg, + lib, + profile, + Kind::Target, + mode, + features, + /*is_std*/ true, + )) }) .collect::>>() } @@ -173,3 +181,33 @@ fn detect_sysroot_src_path(ws: &Workspace<'_>) -> CargoResult { } Ok(src_path) } + +/// Prepare the output directory for the local sysroot. +pub fn prepare_sysroot(layout: &Layout) -> CargoResult<()> { + if let Some(libdir) = layout.sysroot_libdir() { + if libdir.exists() { + paths::remove_dir_all(libdir)?; + } + paths::create_dir_all(libdir)?; + } + Ok(()) +} + +/// Copy an artifact to the sysroot. +pub fn add_sysroot_artifact<'a>( + cx: &Context<'a, '_>, + unit: &Unit<'a>, + rmeta: bool, +) -> CargoResult<()> { + let outputs = cx.outputs(unit)?; + let outputs = outputs + .iter() + .filter(|output| output.flavor == FileFlavor::Linkable { rmeta }) + .map(|output| &output.path); + for path in outputs { + let libdir = cx.files().layout(Kind::Target).sysroot_libdir().unwrap(); + let dst = libdir.join(path.file_name().unwrap()); + paths::link_or_copy(path, dst)?; + } + Ok(()) +} diff --git a/src/cargo/core/compiler/unit.rs b/src/cargo/core/compiler/unit.rs index 122c077f471..62dc506c0d0 100644 --- a/src/cargo/core/compiler/unit.rs +++ b/src/cargo/core/compiler/unit.rs @@ -51,6 +51,8 @@ pub struct UnitInner<'a> { /// The `cfg` features to enable for this unit. /// This must be sorted. pub features: Vec<&'a str>, + /// Whether this is a standard library unit. + pub is_std: bool, } impl UnitInner<'_> { @@ -144,6 +146,7 @@ impl<'a> UnitInterner<'a> { kind: Kind, mode: CompileMode, features: Vec<&'a str>, + is_std: bool, ) -> Unit<'a> { let inner = self.intern_inner(&UnitInner { pkg, @@ -152,6 +155,7 @@ impl<'a> UnitInterner<'a> { kind, mode, features, + is_std, }); Unit { inner } } diff --git a/src/cargo/core/compiler/unit_dependencies.rs b/src/cargo/core/compiler/unit_dependencies.rs index 2d00b7abd7f..936adee365a 100644 --- a/src/cargo/core/compiler/unit_dependencies.rs +++ b/src/cargo/core/compiler/unit_dependencies.rs @@ -573,7 +573,7 @@ fn new_unit_dep_with_profile<'a>( let unit = state .bcx .units - .intern(pkg, target, profile, kind, mode, features); + .intern(pkg, target, profile, kind, mode, features, state.is_std); Ok(UnitDep { unit, unit_for, diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs index 957ceb2429d..ac8dd6d72eb 100644 --- a/src/cargo/ops/cargo_clean.rs +++ b/src/cargo/ops/cargo_clean.rs @@ -94,10 +94,9 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> { ) }; let features = resolve.features_sorted(pkg.package_id()); - units.push( - bcx.units - .intern(pkg, target, profile, *kind, *mode, features), - ); + units.push(bcx.units.intern( + pkg, target, profile, *kind, *mode, features, /*is_std*/ false, + )); } } } diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 9c2aa3f1f81..7b34ebef3a8 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -703,8 +703,15 @@ fn generate_targets<'a>( bcx.build_config.release, ); let features = resolve.features_sorted(pkg.package_id()); - bcx.units - .intern(pkg, target, profile, kind, target_mode, features) + bcx.units.intern( + pkg, + target, + profile, + kind, + target_mode, + features, + /*is_std*/ false, + ) }; // Create a list of proposed targets. From bc5c441b12c4347b41c55dd5886499b664acfb14 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 23 Sep 2019 12:07:24 -0700 Subject: [PATCH 2/8] Change how standard_lib tests work * Minimize the sysroot crates in play * Don't use build scripts to inject args * Use `RUSTC_WRAPPER` to dynamically switch `--sysroot` depending on whether we're building sysroot crates or not. * Minimize dependency graph in sysroot, only have each crate depend on a dummy crates.io crate for testing and otherwise don't depend on anything to load the desired sysroot crate directly. --- tests/testsuite/mock-std/Cargo.toml | 9 +- .../mock-std/src/liballoc/Cargo.toml | 2 +- tests/testsuite/mock-std/src/liballoc/lib.rs | 12 +- .../src/libcompiler_builtins/Cargo.toml | 3 - tests/testsuite/mock-std/src/libcore/build.rs | 23 -- tests/testsuite/mock-std/src/libcore/lib.rs | 9 +- .../mock-std/src/libpanic_unwind/Cargo.toml | 3 - .../mock-std/src/libproc_macro/Cargo.toml | 3 - .../mock-std/src/libproc_macro/lib.rs | 10 +- .../testsuite/mock-std/src/libstd/Cargo.toml | 6 +- tests/testsuite/mock-std/src/libstd/lib.rs | 7 +- .../testsuite/mock-std/src/libtest/Cargo.toml | 5 +- tests/testsuite/mock-std/src/libtest/lib.rs | 3 +- .../rustc-std-workspace-alloc/Cargo.toml | 1 - .../tools/rustc-std-workspace-core/Cargo.toml | 1 - .../tools/rustc-std-workspace-std/Cargo.toml | 1 - tests/testsuite/standard_lib.rs | 228 ++++++++++++------ 17 files changed, 199 insertions(+), 127 deletions(-) delete mode 100644 tests/testsuite/mock-std/src/libcore/build.rs diff --git a/tests/testsuite/mock-std/Cargo.toml b/tests/testsuite/mock-std/Cargo.toml index a2fdae3b7f0..3cc10acb2e4 100644 --- a/tests/testsuite/mock-std/Cargo.toml +++ b/tests/testsuite/mock-std/Cargo.toml @@ -1,9 +1,8 @@ [workspace] members = [ + "src/liballoc", + "src/libcore", + "src/libproc_macro", + "src/libstd", "src/libtest", ] - -[patch.crates-io] -rustc-std-workspace-std = { path = 'src/tools/rustc-std-workspace-std' } -rustc-std-workspace-core = { path = 'src/tools/rustc-std-workspace-core' } -rustc-std-workspace-alloc = { path = 'src/tools/rustc-std-workspace-alloc' } diff --git a/tests/testsuite/mock-std/src/liballoc/Cargo.toml b/tests/testsuite/mock-std/src/liballoc/Cargo.toml index 128600df51a..23034673665 100644 --- a/tests/testsuite/mock-std/src/liballoc/Cargo.toml +++ b/tests/testsuite/mock-std/src/liballoc/Cargo.toml @@ -8,4 +8,4 @@ edition = "2018" path = "lib.rs" [dependencies] -core = { path = "../libcore" } +registry-dep-using-core = { version = "*", features = ['mockbuild'] } diff --git a/tests/testsuite/mock-std/src/liballoc/lib.rs b/tests/testsuite/mock-std/src/liballoc/lib.rs index e29525b6a50..823716e4043 100644 --- a/tests/testsuite/mock-std/src/liballoc/lib.rs +++ b/tests/testsuite/mock-std/src/liballoc/lib.rs @@ -1 +1,11 @@ -pub fn custom_api() {} +#![feature(staged_api)] +#![stable(since = "1.0.0", feature = "dummy")] + +extern crate alloc; + +#[stable(since = "1.0.0", feature = "dummy")] +pub use alloc::*; + +#[stable(since = "1.0.0", feature = "dummy")] +pub fn custom_api() { +} diff --git a/tests/testsuite/mock-std/src/libcompiler_builtins/Cargo.toml b/tests/testsuite/mock-std/src/libcompiler_builtins/Cargo.toml index 27141f23250..1bb02f9907c 100644 --- a/tests/testsuite/mock-std/src/libcompiler_builtins/Cargo.toml +++ b/tests/testsuite/mock-std/src/libcompiler_builtins/Cargo.toml @@ -6,6 +6,3 @@ edition = "2018" [lib] path = "lib.rs" - -[dependencies] -core = { path = "../libcore" } diff --git a/tests/testsuite/mock-std/src/libcore/build.rs b/tests/testsuite/mock-std/src/libcore/build.rs deleted file mode 100644 index 53d4e145d35..00000000000 --- a/tests/testsuite/mock-std/src/libcore/build.rs +++ /dev/null @@ -1,23 +0,0 @@ -//! This build script is basically the whole hack that makes this entire "mock -//! std" feature work. Here we print out `rustc-link-search` pointing to the -//! sysroot of the actual compiler itself, and that way we can indeed implicitly -//! pull in those crates, but only via `extern crate`. That means that we can -//! build tiny shim core/std/etc crates while they actually load all the various -//! language/library details from the actual crates, meaning that instead of -//! literally compiling libstd we compile just our own tiny shims. - -use std::process::Command; -use std::env; - -fn main() { - let output = Command::new("rustc") - .arg("--print") - .arg("sysroot") - .output() - .unwrap(); - assert!(output.status.success()); - let stdout = String::from_utf8(output.stdout).unwrap(); - let stdout = stdout.trim(); - let host = env::var("HOST").unwrap(); - println!("cargo:rustc-link-search={}/lib/rustlib/{}/lib", stdout, host); -} diff --git a/tests/testsuite/mock-std/src/libcore/lib.rs b/tests/testsuite/mock-std/src/libcore/lib.rs index 73e79b9a905..b90ed091414 100644 --- a/tests/testsuite/mock-std/src/libcore/lib.rs +++ b/tests/testsuite/mock-std/src/libcore/lib.rs @@ -1,4 +1,9 @@ -#![no_std] +#![feature(staged_api)] +#![stable(since = "1.0.0", feature = "dummy")] + +#[stable(since = "1.0.0", feature = "dummy")] pub use core::*; -pub fn custom_api() {} +#[stable(since = "1.0.0", feature = "dummy")] +pub fn custom_api() { +} diff --git a/tests/testsuite/mock-std/src/libpanic_unwind/Cargo.toml b/tests/testsuite/mock-std/src/libpanic_unwind/Cargo.toml index af06d7736e1..9dc111d29f0 100644 --- a/tests/testsuite/mock-std/src/libpanic_unwind/Cargo.toml +++ b/tests/testsuite/mock-std/src/libpanic_unwind/Cargo.toml @@ -6,6 +6,3 @@ edition = "2018" [lib] path = "lib.rs" - -[dependencies] -core = { path = "../libcore" } diff --git a/tests/testsuite/mock-std/src/libproc_macro/Cargo.toml b/tests/testsuite/mock-std/src/libproc_macro/Cargo.toml index bc93bfcc785..c400a4a51c0 100644 --- a/tests/testsuite/mock-std/src/libproc_macro/Cargo.toml +++ b/tests/testsuite/mock-std/src/libproc_macro/Cargo.toml @@ -6,6 +6,3 @@ edition = "2018" [lib] path = "lib.rs" - -[dependencies] -std = { path = "../libstd" } diff --git a/tests/testsuite/mock-std/src/libproc_macro/lib.rs b/tests/testsuite/mock-std/src/libproc_macro/lib.rs index 73825ac07c2..82a76840615 100644 --- a/tests/testsuite/mock-std/src/libproc_macro/lib.rs +++ b/tests/testsuite/mock-std/src/libproc_macro/lib.rs @@ -1,3 +1,11 @@ +#![feature(staged_api)] +#![stable(since = "1.0.0", feature = "dummy")] + extern crate proc_macro; + +#[stable(since = "1.0.0", feature = "dummy")] pub use proc_macro::*; -pub fn custom_api() {} + +#[stable(since = "1.0.0", feature = "dummy")] +pub fn custom_api() { +} diff --git a/tests/testsuite/mock-std/src/libstd/Cargo.toml b/tests/testsuite/mock-std/src/libstd/Cargo.toml index 9338f036826..55279ce94bf 100644 --- a/tests/testsuite/mock-std/src/libstd/Cargo.toml +++ b/tests/testsuite/mock-std/src/libstd/Cargo.toml @@ -8,8 +8,4 @@ edition = "2018" path = "lib.rs" [dependencies] -core = { path = "../libcore" } -compiler_builtins = { path = "../libcompiler_builtins" } -panic_unwind = { path = "../libpanic_unwind" } -registry-dep-using-core = { version = "1.0", features = ['mockbuild'] } -registry-dep-using-alloc = { version = "1.0", features = ['mockbuild'] } +registry-dep-using-alloc = { version = "*", features = ['mockbuild'] } diff --git a/tests/testsuite/mock-std/src/libstd/lib.rs b/tests/testsuite/mock-std/src/libstd/lib.rs index e7e64f1f643..4d1723d5ea2 100644 --- a/tests/testsuite/mock-std/src/libstd/lib.rs +++ b/tests/testsuite/mock-std/src/libstd/lib.rs @@ -1,6 +1,9 @@ +#![feature(staged_api)] +#![stable(since = "1.0.0", feature = "dummy")] + +#[stable(since = "1.0.0", feature = "dummy")] pub use std::*; +#[stable(since = "1.0.0", feature = "dummy")] pub fn custom_api() { - registry_dep_using_core::custom_api(); - registry_dep_using_alloc::custom_api(); } diff --git a/tests/testsuite/mock-std/src/libtest/Cargo.toml b/tests/testsuite/mock-std/src/libtest/Cargo.toml index a81a2dd6a2a..dc5f9da56d9 100644 --- a/tests/testsuite/mock-std/src/libtest/Cargo.toml +++ b/tests/testsuite/mock-std/src/libtest/Cargo.toml @@ -9,8 +9,9 @@ path = "lib.rs" [dependencies] proc_macro = { path = "../libproc_macro" } -registry-dep-using-std = { version = "1.0", features = ['mockbuild'] } -std = { path = "../libstd" } +panic_unwind = { path = "../libpanic_unwind" } +compiler_builtins = { path = "../libcompiler_builtins" } +registry-dep-using-std = { version = "*", features = ['mockbuild'] } [features] panic-unwind = [] diff --git a/tests/testsuite/mock-std/src/libtest/lib.rs b/tests/testsuite/mock-std/src/libtest/lib.rs index 34c0e532ba6..4f5b7b1bff2 100644 --- a/tests/testsuite/mock-std/src/libtest/lib.rs +++ b/tests/testsuite/mock-std/src/libtest/lib.rs @@ -1,9 +1,10 @@ +#![feature(staged_api)] #![feature(test)] +#![unstable(feature = "test", issue = "0")] extern crate test; pub use test::*; pub fn custom_api() { - registry_dep_using_std::custom_api(); } diff --git a/tests/testsuite/mock-std/src/tools/rustc-std-workspace-alloc/Cargo.toml b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-alloc/Cargo.toml index 54d9ff4fd59..18fc7004259 100644 --- a/tests/testsuite/mock-std/src/tools/rustc-std-workspace-alloc/Cargo.toml +++ b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-alloc/Cargo.toml @@ -5,7 +5,6 @@ authors = ["Alex Crichton "] edition = "2018" [lib] -name = "alloc" path = "lib.rs" [dependencies] diff --git a/tests/testsuite/mock-std/src/tools/rustc-std-workspace-core/Cargo.toml b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-core/Cargo.toml index d62698f62f3..39d704fd995 100644 --- a/tests/testsuite/mock-std/src/tools/rustc-std-workspace-core/Cargo.toml +++ b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-core/Cargo.toml @@ -5,7 +5,6 @@ authors = ["Alex Crichton "] edition = "2018" [lib] -name = "core" path = "lib.rs" [dependencies] diff --git a/tests/testsuite/mock-std/src/tools/rustc-std-workspace-std/Cargo.toml b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-std/Cargo.toml index 0a4bd3a7e46..9cf5530ae15 100644 --- a/tests/testsuite/mock-std/src/tools/rustc-std-workspace-std/Cargo.toml +++ b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-std/Cargo.toml @@ -5,7 +5,6 @@ authors = ["Alex Crichton "] edition = "2018" [lib] -name = "std" path = "lib.rs" [dependencies] diff --git a/tests/testsuite/standard_lib.rs b/tests/testsuite/standard_lib.rs index 80db0fcee20..621e35f0afd 100644 --- a/tests/testsuite/standard_lib.rs +++ b/tests/testsuite/standard_lib.rs @@ -1,11 +1,19 @@ use cargo_test_support::registry::{Dependency, Package}; +use cargo_test_support::ProjectBuilder; use cargo_test_support::{is_nightly, paths, project, rustc_host, Execs}; +use std::path::PathBuf; +use std::process::Command; -fn setup() -> bool { +struct Setup { + rustc_wrapper: PathBuf, + real_sysroot: String, +} + +fn setup() -> Option { if !is_nightly() { // -Zbuild-std is nightly // We don't want these tests to run on rust-lang/rust. - return false; + return None; } // Our mock sysroot requires a few packages from crates.io, so make sure @@ -19,7 +27,6 @@ fn setup() -> bool { #[cfg(feature = \"mockbuild\")] pub fn custom_api() { - core::custom_api(); } #[cfg(not(feature = \"mockbuild\"))] @@ -41,8 +48,6 @@ fn setup() -> bool { #[cfg(feature = \"mockbuild\")] pub fn custom_api() { - core::custom_api(); - alloc::custom_api(); } #[cfg(not(feature = \"mockbuild\"))] @@ -65,7 +70,6 @@ fn setup() -> bool { " #[cfg(feature = \"mockbuild\")] pub fn custom_api() { - std::custom_api(); } #[cfg(not(feature = \"mockbuild\"))] @@ -77,10 +81,57 @@ fn setup() -> bool { .add_dep(Dependency::new("rustc-std-workspace-std", "*").optional(true)) .feature("mockbuild", &["rustc-std-workspace-std"]) .publish(); - return true; + + let p = ProjectBuilder::new(paths::root().join("rustc-wrapper")) + .file( + "src/main.rs", + r#" + use std::process::Command; + use std::env; + fn main() { + let mut args = env::args().skip(1).collect::>(); + + let crates = [ + "alloc", + "compiler_builtins", + "core", + "panic_unwind", + "proc_macro", + "std", + "test", + ]; + let is_sysroot_crate = args.iter() + .any(|a| a.starts_with("rustc_std_workspace") || crates.iter().any(|b| a == b)); + + if is_sysroot_crate { + let arg = args.iter().position(|a| a == "--sysroot").unwrap(); + args[arg + 1] = env::var("REAL_SYSROOT").unwrap(); + } + + let ret = Command::new(&args[0]).args(&args[1..]).status().unwrap(); + std::process::exit(ret.code().unwrap_or(1)); + } + "#, + ) + .build(); + p.cargo("build").run(); + + let output = Command::new("rustc") + .arg("--print") + .arg("sysroot") + .output() + .unwrap(); + assert!(output.status.success()); + let real_sysroot = String::from_utf8(output.stdout).unwrap(); + let real_sysroot = real_sysroot.trim(); + + return Some(Setup { + rustc_wrapper: p.bin("foo"), + real_sysroot: real_sysroot.to_string(), + }); } -fn enable_build_std(e: &mut Execs, arg: Option<&str>) { +fn enable_build_std(e: &mut Execs, setup: &Setup, arg: Option<&str>) { // First up, force Cargo to use our "mock sysroot" which mimics what // libstd looks like upstream. let root = paths::root(); @@ -94,33 +145,51 @@ fn enable_build_std(e: &mut Execs, arg: Option<&str>) { .join("tests/testsuite/mock-std"); e.env("__CARGO_TESTS_ONLY_SRC_ROOT", &root); - // Next, make sure it doesn't have implicit access to the host's sysroot - e.env("RUSTFLAGS", "--sysroot=/path/to/nowhere"); - - // And finally actually enable `build-std` for now + // Actually enable `-Zbuild-std` for now let arg = match arg { Some(s) => format!("-Zbuild-std={}", s), None => "-Zbuild-std".to_string(), }; e.arg(arg); e.masquerade_as_nightly_cargo(); + + // We do various shenanigans to ensure our "mock sysroot" actually links + // with the real sysroot, so we don't have to actually recompile std for + // each test. Perform all that logic here, namely: + // + // * RUSTC_WRAPPER - uses our shim executable built above to control rustc + // * REAL_SYSROOT - used by the shim executable to swap out to the real + // sysroot temporarily for some compilations + // * RUST{,DOC}FLAGS - an extra `-L` argument to ensure we can always load + // crates from the sysroot, but only indirectly through other crates. + e.env("RUSTC_WRAPPER", &setup.rustc_wrapper); + e.env("REAL_SYSROOT", &setup.real_sysroot); + let libdir = format!("/lib/rustlib/{}/lib", rustc_host()); + e.env( + "RUSTFLAGS", + format!("-Ldependency={}{}", setup.real_sysroot, libdir), + ); + e.env( + "RUSTDOCFLAGS", + format!("-Ldependency={}{}", setup.real_sysroot, libdir), + ); } // Helper methods used in the tests below trait BuildStd: Sized { - fn build_std(&mut self) -> &mut Self; - fn build_std_arg(&mut self, arg: &str) -> &mut Self; + fn build_std(&mut self, setup: &Setup) -> &mut Self; + fn build_std_arg(&mut self, setup: &Setup, arg: &str) -> &mut Self; fn target_host(&mut self) -> &mut Self; } impl BuildStd for Execs { - fn build_std(&mut self) -> &mut Self { - enable_build_std(self, None); + fn build_std(&mut self, setup: &Setup) -> &mut Self { + enable_build_std(self, setup, None); self } - fn build_std_arg(&mut self, arg: &str) -> &mut Self { - enable_build_std(self, Some(arg)); + fn build_std_arg(&mut self, setup: &Setup, arg: &str) -> &mut Self { + enable_build_std(self, setup, Some(arg)); self } @@ -132,9 +201,10 @@ impl BuildStd for Execs { #[cargo_test] fn basic() { - if !setup() { - return; - } + let setup = match setup() { + Some(s) => s, + None => return, + }; let p = project() .file( @@ -187,27 +257,28 @@ fn basic() { ) .build(); - p.cargo("check").build_std().target_host().run(); - p.cargo("build").build_std().target_host().run(); - p.cargo("run").build_std().target_host().run(); - p.cargo("test").build_std().target_host().run(); + p.cargo("check").build_std(&setup).target_host().run(); + p.cargo("build").build_std(&setup).target_host().run(); + p.cargo("run").build_std(&setup).target_host().run(); + p.cargo("test").build_std(&setup).target_host().run(); } #[cargo_test] fn simple_lib_std() { - if !setup() { - return; - } + let setup = match setup() { + Some(s) => s, + None => return, + }; let p = project().file("src/lib.rs", "").build(); p.cargo("build -v") - .build_std() + .build_std(&setup) .target_host() - .with_stderr_contains("[RUNNING] `rustc [..]--crate-name std [..]") + .with_stderr_contains("[RUNNING] `[..]--crate-name std [..]`") .run(); // Check freshness. p.change_file("src/lib.rs", " "); p.cargo("build -v") - .build_std() + .build_std(&setup) .target_host() .with_stderr_contains("[FRESH] std[..]") .run(); @@ -215,18 +286,20 @@ fn simple_lib_std() { #[cargo_test] fn simple_bin_std() { - if !setup() { - return; - } + let setup = match setup() { + Some(s) => s, + None => return, + }; let p = project().file("src/main.rs", "fn main() {}").build(); - p.cargo("run -v").build_std().target_host().run(); + p.cargo("run -v").build_std(&setup).target_host().run(); } #[cargo_test] fn lib_nostd() { - if !setup() { - return; - } + let setup = match setup() { + Some(s) => s, + None => return, + }; let p = project() .file( "src/lib.rs", @@ -239,7 +312,7 @@ fn lib_nostd() { ) .build(); p.cargo("build -v --lib") - .build_std_arg("core") + .build_std_arg(&setup, "core") .target_host() .with_stderr_does_not_contain("[..]libstd[..]") .run(); @@ -247,15 +320,16 @@ fn lib_nostd() { #[cargo_test] fn check_core() { - if !setup() { - return; - } + let setup = match setup() { + Some(s) => s, + None => return, + }; let p = project() .file("src/lib.rs", "#![no_std] fn unused_fn() {}") .build(); p.cargo("check -v") - .build_std_arg("core") + .build_std_arg(&setup, "core") .target_host() .with_stderr_contains("[WARNING] [..]unused_fn[..]`") .run(); @@ -263,9 +337,10 @@ fn check_core() { #[cargo_test] fn depend_same_as_std() { - if !setup() { - return; - } + let setup = match setup() { + Some(s) => s, + None => return, + }; let p = project() .file( @@ -294,14 +369,15 @@ fn depend_same_as_std() { ) .build(); - p.cargo("build -v").build_std().target_host().run(); + p.cargo("build -v").build_std(&setup).target_host().run(); } #[cargo_test] fn test() { - if !setup() { - return; - } + let setup = match setup() { + Some(s) => s, + None => return, + }; let p = project() .file( "src/lib.rs", @@ -318,7 +394,7 @@ fn test() { .build(); p.cargo("test -v") - .build_std() + .build_std(&setup) .target_host() .with_stdout_contains("test tests::it_works ... ok") .run(); @@ -326,9 +402,10 @@ fn test() { #[cargo_test] fn target_proc_macro() { - if !setup() { - return; - } + let setup = match setup() { + Some(s) => s, + None => return, + }; let p = project() .file( "src/lib.rs", @@ -341,14 +418,15 @@ fn target_proc_macro() { ) .build(); - p.cargo("build -v").build_std().target_host().run(); + p.cargo("build -v").build_std(&setup).target_host().run(); } #[cargo_test] fn bench() { - if !setup() { - return; - } + let setup = match setup() { + Some(s) => s, + None => return, + }; let p = project() .file( "src/lib.rs", @@ -364,14 +442,15 @@ fn bench() { ) .build(); - p.cargo("bench -v").build_std().target_host().run(); + p.cargo("bench -v").build_std(&setup).target_host().run(); } #[cargo_test] fn doc() { - if !setup() { - return; - } + let setup = match setup() { + Some(s) => s, + None => return, + }; let p = project() .file( "src/lib.rs", @@ -382,14 +461,15 @@ fn doc() { ) .build(); - p.cargo("doc -v").build_std().target_host().run(); + p.cargo("doc -v").build_std(&setup).target_host().run(); } #[cargo_test] fn check_std() { - if !setup() { - return; - } + let setup = match setup() { + Some(s) => s, + None => return, + }; let p = project() .file( "src/lib.rs", @@ -413,20 +493,21 @@ fn check_std() { .build(); p.cargo("check -v --all-targets") - .build_std() + .build_std(&setup) .target_host() .run(); p.cargo("check -v --all-targets --profile=test") - .build_std() + .build_std(&setup) .target_host() .run(); } #[cargo_test] fn doctest() { - if !setup() { - return; - } + let setup = match setup() { + Some(s) => s, + None => return, + }; let p = project() .file( "src/lib.rs", @@ -440,5 +521,8 @@ fn doctest() { ) .build(); - p.cargo("test --doc -v").build_std().target_host().run(); + p.cargo("test --doc -v") + .build_std(&setup) + .target_host() + .run(); } From 53a3db05a69a769d09b3883aa7b4984fbe6a7383 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 23 Sep 2019 18:29:49 -0700 Subject: [PATCH 3/8] Some more --sysroot tests. --- crates/cargo-test-support/src/paths.rs | 12 +++++ tests/build-std/main.rs | 16 ++++++ tests/testsuite/standard_lib.rs | 67 +++++++++++++++++++++----- 3 files changed, 83 insertions(+), 12 deletions(-) diff --git a/crates/cargo-test-support/src/paths.rs b/crates/cargo-test-support/src/paths.rs index 6b3af85c6d1..f2e15441a71 100644 --- a/crates/cargo-test-support/src/paths.rs +++ b/crates/cargo-test-support/src/paths.rs @@ -6,6 +6,7 @@ use std::env; use std::fs; use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; +use std::process::Command; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Mutex; @@ -252,3 +253,14 @@ pub fn get_lib_extension(kind: &str) -> &str { _ => unreachable!(), } } + +/// Returns the sysroot as queried from rustc. +pub fn sysroot() -> String { + let output = Command::new("rustc") + .arg("--print=sysroot") + .output() + .expect("rustc to run"); + assert!(output.status.success()); + let sysroot = String::from_utf8(output.stdout).unwrap(); + sysroot.trim().to_string() +} diff --git a/tests/build-std/main.rs b/tests/build-std/main.rs index 6e2dbc03019..345b16c9e07 100644 --- a/tests/build-std/main.rs +++ b/tests/build-std/main.rs @@ -19,6 +19,8 @@ //! Otherwise the tests are skipped. use cargo_test_support::*; +use std::env; +use std::path::Path; fn enable_build_std(e: &mut Execs, arg: Option<&str>) { e.env_remove("CARGO_HOME"); @@ -174,7 +176,21 @@ fn custom_test_framework() { ) .build(); + // This is a bit of a hack to use the rust-lld that ships with most toolchains. + let sysroot = paths::sysroot(); + let sysroot = Path::new(&sysroot); + let sysroot_bin = sysroot + .join("lib") + .join("rustlib") + .join(rustc_host()) + .join("bin"); + let path = env::var_os("PATH").unwrap_or_default(); + let mut paths = env::split_paths(&path).collect::>(); + paths.insert(0, sysroot_bin); + let new_path = env::join_paths(paths).unwrap(); + p.cargo("test --target target.json --no-run -v") + .env("PATH", new_path) .build_std_arg("core") .run(); } diff --git a/tests/testsuite/standard_lib.rs b/tests/testsuite/standard_lib.rs index 621e35f0afd..6b3aaf0f4dc 100644 --- a/tests/testsuite/standard_lib.rs +++ b/tests/testsuite/standard_lib.rs @@ -2,7 +2,6 @@ use cargo_test_support::registry::{Dependency, Package}; use cargo_test_support::ProjectBuilder; use cargo_test_support::{is_nightly, paths, project, rustc_host, Execs}; use std::path::PathBuf; -use std::process::Command; struct Setup { rustc_wrapper: PathBuf, @@ -116,18 +115,9 @@ fn setup() -> Option { .build(); p.cargo("build").run(); - let output = Command::new("rustc") - .arg("--print") - .arg("sysroot") - .output() - .unwrap(); - assert!(output.status.success()); - let real_sysroot = String::from_utf8(output.stdout).unwrap(); - let real_sysroot = real_sysroot.trim(); - return Some(Setup { rustc_wrapper: p.bin("foo"), - real_sysroot: real_sysroot.to_string(), + real_sysroot: paths::sysroot(), }); } @@ -514,7 +504,7 @@ fn doctest() { r#" /// Doc /// ``` - /// assert_eq!(1, 1); + /// std::custom_api(); /// ``` pub fn f() {} "#, @@ -523,6 +513,59 @@ fn doctest() { p.cargo("test --doc -v") .build_std(&setup) + .with_stdout_contains("test src/lib.rs - f [..] ... ok") .target_host() .run(); } + +#[cargo_test] +fn no_implicit_alloc() { + // Demonstrate that alloc is not implicitly in scope. + let setup = match setup() { + Some(s) => s, + None => return, + }; + let p = project() + .file( + "src/lib.rs", + r#" + pub fn f() { + let _: Vec = alloc::vec::Vec::new(); + } + "#, + ) + .build(); + + p.cargo("build -v") + .build_std(&setup) + .target_host() + .with_stderr_contains("[..]use of undeclared [..]`alloc`") + .with_status(101) + .run(); +} + +#[cargo_test] +fn macro_expanded_shadow() { + // This tests a bug caused by the previous use of `--extern` to directly + // load sysroot crates. This necessitated the switch to `--sysroot` to + // retain existing behavior. See + // https://github.com/rust-lang/wg-cargo-std-aware/issues/40 for more + // detail. + let setup = match setup() { + Some(s) => s, + None => return, + }; + let p = project() + .file( + "src/lib.rs", + r#" + macro_rules! a { + () => (extern crate std as alloc;) + } + a!(); + "#, + ) + .build(); + + p.cargo("build -v").build_std(&setup).target_host().run(); +} From d0ab04add4361c23b02d7e41a74a8ea348e7897f Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 24 Sep 2019 12:45:32 -0700 Subject: [PATCH 4/8] Simplify mock rustc wrapper. --- tests/testsuite/standard_lib.rs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/tests/testsuite/standard_lib.rs b/tests/testsuite/standard_lib.rs index 6b3aaf0f4dc..5e6ae6126c1 100644 --- a/tests/testsuite/standard_lib.rs +++ b/tests/testsuite/standard_lib.rs @@ -90,18 +90,7 @@ fn setup() -> Option { fn main() { let mut args = env::args().skip(1).collect::>(); - let crates = [ - "alloc", - "compiler_builtins", - "core", - "panic_unwind", - "proc_macro", - "std", - "test", - ]; - let is_sysroot_crate = args.iter() - .any(|a| a.starts_with("rustc_std_workspace") || crates.iter().any(|b| a == b)); - + let is_sysroot_crate = env::var_os("RUSTC_BOOTSTRAP").is_some(); if is_sysroot_crate { let arg = args.iter().position(|a| a == "--sysroot").unwrap(); args[arg + 1] = env::var("REAL_SYSROOT").unwrap(); From 581da42ea6f448b1413232ab4abebc657b90e99b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 24 Sep 2019 13:50:34 -0700 Subject: [PATCH 5/8] Don't add sysroot lib path to dylib path for build-std. --- src/cargo/core/compiler/compilation.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cargo/core/compiler/compilation.rs b/src/cargo/core/compiler/compilation.rs index 65b0603f652..2f0b190eb19 100644 --- a/src/cargo/core/compiler/compilation.rs +++ b/src/cargo/core/compiler/compilation.rs @@ -203,7 +203,13 @@ impl<'cfg> Compilation<'cfg> { super::filter_dynamic_search_path(self.native_dirs.iter(), &self.root_output); search_path.push(self.deps_output.clone()); search_path.push(self.root_output.clone()); - search_path.push(self.target_dylib_path.clone()); + // For build-std, we don't want to accidentally pull in any shared + // libs from the sysroot that ships with rustc. This may not be + // required (at least I cannot craft a situation where it + // matters), but is here to be safe. + if self.config.cli_unstable().build_std.is_none() { + search_path.push(self.target_dylib_path.clone()); + } search_path }; From 3afb5d7dc684a5cf5d224850ec1775c21ba7cc99 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 24 Sep 2019 13:51:11 -0700 Subject: [PATCH 6/8] Add warning when mixing -Zbuild-std with --build-plan. --- src/cargo/ops/cargo_compile.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 7b34ebef3a8..6c76cb7576c 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -309,6 +309,11 @@ pub fn compile_ws<'a>( let (mut packages, resolve_with_overrides) = resolve; let std_resolve = if let Some(crates) = &config.cli_unstable().build_std { + if build_config.build_plan { + config + .shell() + .warn("-Zbuild-std does not currently fully support --build-plan")?; + } if build_config.requested_target.is_none() { // TODO: This should eventually be fixed. Unfortunately it is not // easy to get the host triple in BuildConfig. Consider changing From abe92bcc1716ab25f4760fac32d2db422f2cc2d1 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 24 Sep 2019 14:49:31 -0700 Subject: [PATCH 7/8] Add some comments about Layout naming and .sysroot. --- src/cargo/core/compiler/layout.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/cargo/core/compiler/layout.rs b/src/cargo/core/compiler/layout.rs index 0e192e20dc6..b24c1b58e8f 100644 --- a/src/cargo/core/compiler/layout.rs +++ b/src/cargo/core/compiler/layout.rs @@ -12,6 +12,10 @@ //! .rustc-info.json //! //! # All final artifacts are linked into this directory from `deps`. +//! # Note that named profiles will soon be included as separate directories +//! # here. They have a restricted format, similar to Rust identifiers, so +//! # Cargo-specific directories added in the future should use some prefix +//! # like `.` to avoid name collisions. //! debug/ # or release/ //! //! # File used to lock the directory to prevent multiple cargo processes @@ -46,6 +50,11 @@ //! # incremental is enabled. //! incremental/ //! +//! # The sysroot for -Zbuild-std builds. This only appears in +//! # target-triple directories (not host), and only if -Zbuild-std is +//! # enabled. +//! .sysroot/ +//! //! # This is the location at which the output of all custom build //! # commands are rooted. //! build/ @@ -177,6 +186,7 @@ impl Layout { // Compute the sysroot path for the build-std feature. let build_std = ws.config().cli_unstable().build_std.as_ref(); let (sysroot, sysroot_libdir) = if let Some(tp) = build_std.and(triple_path) { + // This uses a leading dot to avoid collision with named profiles. let sysroot = dest.join(".sysroot"); let sysroot_libdir = sysroot.join("lib").join("rustlib").join(tp).join("lib"); (Some(sysroot), Some(sysroot_libdir)) From 9d86d8693248a5747377eb41584c6e863c5736ca Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 24 Sep 2019 15:29:04 -0700 Subject: [PATCH 8/8] Add comment for unusual placement of add_sysroot_artifact. --- src/cargo/core/compiler/job_queue.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/cargo/core/compiler/job_queue.rs b/src/cargo/core/compiler/job_queue.rs index 2d324c2a238..ef597aa0071 100644 --- a/src/cargo/core/compiler/job_queue.rs +++ b/src/cargo/core/compiler/job_queue.rs @@ -619,6 +619,19 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> { Artifact::Metadata => self.timings.unit_rmeta_finished(id, unlocked), } if unit.is_std && unit.kind == super::Kind::Target && !cx.bcx.build_config.build_plan { + // This is a bit of an unusual place to copy files around, and + // ideally this would be somewhere like the Work closure + // (`link_targets`). The tricky issue is handling rmeta files for + // pipelining. Since those are emitted asynchronously, the code + // path (like `on_stderr_line`) does not have enough information + // to know where the sysroot is, and that it is an std unit. If + // possible, it might be nice to eventually move this to the + // worker thread, but may be tricky to have the paths available. + // Another possibility is to disable pipelining between std -> + // non-std. The pipelining opportunities are small, and are not a + // huge win (in a full build, only proc_macro overlaps for 2 + // seconds out of a 90s build on my system). Care must also be + // taken to properly copy these artifacts for Fresh units. let rmeta = artifact == Artifact::Metadata; standard_lib::add_sysroot_artifact(cx, unit, rmeta)?; }