Skip to content

Commit 662a965

Browse files
committed
Auto merge of rust-lang#7699 - ehuss:build-std-no-sysroot, r=alexcrichton
Switch build-std to use --extern Switch `build-std` to use `--extern` flags instead of `--sysroot`. This is mostly a revert of rust-lang#7421. It uses the new extern flag options introduced in rust-lang/rust#67074. It avoids modifying the extern prelude which was the source of the problem of rust-lang/wg-cargo-std-aware#40. Closes rust-lang/wg-cargo-std-aware#49 Reopens rust-lang/wg-cargo-std-aware#31
2 parents 89d4ab5 + 1c779ac commit 662a965

File tree

9 files changed

+86
-174
lines changed

9 files changed

+86
-174
lines changed

src/cargo/core/compiler/compilation.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
use std::collections::{BTreeSet, HashMap, HashSet};
22
use std::env;
3-
use std::ffi::OsStr;
3+
use std::ffi::{OsStr, OsString};
44
use std::path::PathBuf;
55

66
use cargo_platform::CfgExpr;
77
use semver::Version;
88

99
use super::BuildContext;
1010
use crate::core::compiler::CompileKind;
11-
use crate::core::{Edition, InternedString, Package, PackageId, Target};
11+
use crate::core::{Edition, Package, PackageId, Target};
1212
use crate::util::{self, join_paths, process, CargoResult, Config, ProcessBuilder};
1313

1414
pub struct Doctest {
1515
/// The package being doc-tested.
1616
pub package: Package,
1717
/// The target being tested (currently always the package's lib).
1818
pub target: Target,
19-
/// Extern dependencies needed by `rustdoc`. The path is the location of
20-
/// the compiled lib.
21-
pub deps: Vec<(InternedString, PathBuf)>,
19+
/// Arguments needed to pass to rustdoc to run this test.
20+
pub args: Vec<OsString>,
21+
/// Whether or not -Zunstable-options is needed.
22+
pub unstable_opts: bool,
2223
}
2324

2425
/// A structure returning the result of a compilation.

src/cargo/core/compiler/context/mod.rs

+5-31
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
#![allow(deprecated)]
22
use std::collections::{BTreeSet, HashMap, HashSet};
3-
use std::ffi::OsStr;
43
use std::path::PathBuf;
54
use std::sync::{Arc, Mutex};
65

76
use filetime::FileTime;
87
use jobserver::Client;
98

10-
use crate::core::compiler::compilation;
11-
use crate::core::compiler::Unit;
9+
use crate::core::compiler::{self, compilation, Unit};
1210
use crate::core::PackageId;
1311
use crate::util::errors::{CargoResult, CargoResultExt};
1412
use crate::util::{internal, profile, Config};
@@ -18,7 +16,6 @@ use super::custom_build::{self, BuildDeps, BuildScriptOutputs, BuildScripts};
1816
use super::fingerprint::Fingerprint;
1917
use super::job_queue::JobQueue;
2018
use super::layout::Layout;
21-
use super::standard_lib;
2219
use super::unit_dependencies::{UnitDep, UnitGraph};
2320
use super::{BuildContext, Compilation, CompileKind, CompileMode, Executor, FileFlavor};
2421

@@ -206,35 +203,13 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
206203

207204
// Collect information for `rustdoc --test`.
208205
if unit.mode.is_doc_test() {
209-
// Note that we can *only* doc-test rlib outputs here. A
210-
// staticlib output cannot be linked by the compiler (it just
211-
// doesn't do that). A dylib output, however, can be linked by
212-
// the compiler, but will always fail. Currently all dylibs are
213-
// built as "static dylibs" where the standard library is
214-
// statically linked into the dylib. The doc tests fail,
215-
// however, for now as they try to link the standard library
216-
// dynamically as well, causing problems. As a result we only
217-
// pass `--extern` for rlib deps and skip out on all other
218-
// artifacts.
219-
let mut doctest_deps = Vec::new();
220-
for dep in self.unit_deps(unit) {
221-
if dep.unit.target.is_lib() && dep.unit.mode == CompileMode::Build {
222-
let outputs = self.outputs(&dep.unit)?;
223-
let outputs = outputs.iter().filter(|output| {
224-
output.path.extension() == Some(OsStr::new("rlib"))
225-
|| dep.unit.target.for_host()
226-
});
227-
for output in outputs {
228-
doctest_deps.push((dep.extern_crate_name, output.path.clone()));
229-
}
230-
}
231-
}
232-
// Help with tests to get a stable order with renamed deps.
233-
doctest_deps.sort();
206+
let mut unstable_opts = false;
207+
let args = compiler::extern_args(&self, unit, &mut unstable_opts)?;
234208
self.compilation.to_doc_test.push(compilation::Doctest {
235209
package: unit.pkg.clone(),
236210
target: unit.target.clone(),
237-
deps: doctest_deps,
211+
args,
212+
unstable_opts,
238213
});
239214
}
240215

@@ -312,7 +287,6 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
312287
let mut targets = HashMap::new();
313288
if let CompileKind::Target(target) = self.bcx.build_config.requested_kind {
314289
let layout = Layout::new(self.bcx.ws, Some(target), &dest)?;
315-
standard_lib::prepare_sysroot(&layout)?;
316290
targets.insert(target, layout);
317291
}
318292
self.primary_packages

src/cargo/core/compiler/job_queue.rs

-18
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use super::job::{
1717
Freshness::{self, Dirty, Fresh},
1818
Job,
1919
};
20-
use super::standard_lib;
2120
use super::timings::Timings;
2221
use super::{BuildContext, BuildPlan, CompileMode, Context, Unit};
2322
use crate::core::compiler::ProfileKind;
@@ -618,23 +617,6 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
618617
Artifact::All => self.timings.unit_finished(id, unlocked),
619618
Artifact::Metadata => self.timings.unit_rmeta_finished(id, unlocked),
620619
}
621-
if unit.is_std && !unit.kind.is_host() && !cx.bcx.build_config.build_plan {
622-
// This is a bit of an unusual place to copy files around, and
623-
// ideally this would be somewhere like the Work closure
624-
// (`link_targets`). The tricky issue is handling rmeta files for
625-
// pipelining. Since those are emitted asynchronously, the code
626-
// path (like `on_stderr_line`) does not have enough information
627-
// to know where the sysroot is, and that it is an std unit. If
628-
// possible, it might be nice to eventually move this to the
629-
// worker thread, but may be tricky to have the paths available.
630-
// Another possibility is to disable pipelining between std ->
631-
// non-std. The pipelining opportunities are small, and are not a
632-
// huge win (in a full build, only proc_macro overlaps for 2
633-
// seconds out of a 90s build on my system). Care must also be
634-
// taken to properly copy these artifacts for Fresh units.
635-
let rmeta = artifact == Artifact::Metadata;
636-
standard_lib::add_sysroot_artifact(cx, unit, rmeta)?;
637-
}
638620
Ok(())
639621
}
640622

src/cargo/core/compiler/layout.rs

-36
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,6 @@
5353
//! # incremental is enabled.
5454
//! incremental/
5555
//!
56-
//! # The sysroot for -Zbuild-std builds. This only appears in
57-
//! # target-triple directories (not host), and only if -Zbuild-std is
58-
//! # enabled.
59-
//! .sysroot/
60-
//!
6156
//! # This is the location at which the output of all custom build
6257
//! # commands are rooted.
6358
//! build/
@@ -129,10 +124,6 @@ pub struct Layout {
129124
examples: PathBuf,
130125
/// The directory for rustdoc output: `$root/doc`
131126
doc: PathBuf,
132-
/// The local sysroot for the build-std feature.
133-
sysroot: Option<PathBuf>,
134-
/// The "lib" directory within `sysroot`.
135-
sysroot_libdir: Option<PathBuf>,
136127
/// The lockfile for a build (`.cargo-lock`). Will be unlocked when this
137128
/// struct is `drop`ped.
138129
_lock: FileLock,
@@ -176,21 +167,6 @@ impl Layout {
176167
let root = root.into_path_unlocked();
177168
let dest = dest.into_path_unlocked();
178169

179-
// Compute the sysroot path for the build-std feature.
180-
let build_std = ws.config().cli_unstable().build_std.as_ref();
181-
let (sysroot, sysroot_libdir) = if let Some(target) = build_std.and(target) {
182-
// This uses a leading dot to avoid collision with named profiles.
183-
let sysroot = dest.join(".sysroot");
184-
let sysroot_libdir = sysroot
185-
.join("lib")
186-
.join("rustlib")
187-
.join(target.short_name())
188-
.join("lib");
189-
(Some(sysroot), Some(sysroot_libdir))
190-
} else {
191-
(None, None)
192-
};
193-
194170
Ok(Layout {
195171
deps: dest.join("deps"),
196172
build: dest.join("build"),
@@ -200,8 +176,6 @@ impl Layout {
200176
doc: root.join("doc"),
201177
root,
202178
dest,
203-
sysroot,
204-
sysroot_libdir,
205179
_lock: lock,
206180
})
207181
}
@@ -249,16 +223,6 @@ impl Layout {
249223
pub fn build(&self) -> &Path {
250224
&self.build
251225
}
252-
/// The local sysroot for the build-std feature.
253-
///
254-
/// Returns None if build-std is not enabled or this is the Host layout.
255-
pub fn sysroot(&self) -> Option<&Path> {
256-
self.sysroot.as_ref().map(|p| p.as_ref())
257-
}
258-
/// The "lib" directory within `sysroot`.
259-
pub fn sysroot_libdir(&self) -> Option<&Path> {
260-
self.sysroot_libdir.as_ref().map(|p| p.as_ref())
261-
}
262226
}
263227

264228
#[cfg(not(target_os = "macos"))]

src/cargo/core/compiler/mod.rs

+53-42
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ use self::unit_dependencies::UnitDep;
4343
pub use crate::core::compiler::unit::{Unit, UnitInterner};
4444
use crate::core::manifest::TargetSourcePath;
4545
use crate::core::profiles::{Lto, PanicStrategy, Profile};
46-
use crate::core::Feature;
47-
use crate::core::{PackageId, Target};
46+
use crate::core::{Feature, InternedString, PackageId, Target};
4847
use crate::util::errors::{self, CargoResult, CargoResultExt, Internal, ProcessError};
4948
use crate::util::machine_message::Message;
5049
use crate::util::paths;
@@ -894,8 +893,7 @@ fn build_deps_args<'a, 'cfg>(
894893
});
895894
}
896895

897-
// Create Vec since mutable cx is needed in closure below.
898-
let deps = Vec::from(cx.unit_deps(unit));
896+
let deps = cx.unit_deps(unit);
899897

900898
// If there is not one linkable target but should, rustc fails later
901899
// on if there is an `extern crate` for it. This may turn into a hard
@@ -922,23 +920,14 @@ fn build_deps_args<'a, 'cfg>(
922920

923921
let mut unstable_opts = false;
924922

925-
if let Some(sysroot) = cx.files().layout(unit.kind).sysroot() {
926-
if !unit.kind.is_host() {
927-
cmd.arg("--sysroot").arg(sysroot);
928-
}
929-
}
930-
931923
for dep in deps {
932-
if !unit.is_std && dep.unit.is_std {
933-
// Dependency to sysroot crate uses --sysroot.
934-
continue;
935-
}
936924
if dep.unit.mode.is_run_custom_build() {
937925
cmd.env("OUT_DIR", &cx.files().build_script_out_dir(&dep.unit));
938926
}
939-
if dep.unit.target.linkable() && !dep.unit.mode.is_doc() {
940-
link_to(cmd, cx, unit, &dep, &mut unstable_opts)?;
941-
}
927+
}
928+
929+
for arg in extern_args(cx, unit, &mut unstable_opts)? {
930+
cmd.arg(arg);
942931
}
943932

944933
// This will only be set if we're already using a feature
@@ -948,37 +937,51 @@ fn build_deps_args<'a, 'cfg>(
948937
}
949938

950939
return Ok(());
940+
}
951941

952-
fn link_to<'a, 'cfg>(
953-
cmd: &mut ProcessBuilder,
954-
cx: &mut Context<'a, 'cfg>,
955-
current: &Unit<'a>,
956-
dep: &UnitDep<'a>,
957-
need_unstable_opts: &mut bool,
958-
) -> CargoResult<()> {
942+
/// Generates a list of `--extern` arguments.
943+
pub fn extern_args<'a>(
944+
cx: &Context<'a, '_>,
945+
unit: &Unit<'a>,
946+
unstable_opts: &mut bool,
947+
) -> CargoResult<Vec<OsString>> {
948+
let mut result = Vec::new();
949+
let deps = cx.unit_deps(unit);
950+
951+
// Closure to add one dependency to `result`.
952+
let mut link_to = |dep: &UnitDep<'a>,
953+
extern_crate_name: InternedString,
954+
noprelude: bool|
955+
-> CargoResult<()> {
959956
let mut value = OsString::new();
960-
value.push(dep.extern_crate_name.as_str());
957+
let mut opts = Vec::new();
958+
if unit
959+
.pkg
960+
.manifest()
961+
.features()
962+
.require(Feature::public_dependency())
963+
.is_ok()
964+
&& !dep.public
965+
{
966+
opts.push("priv");
967+
*unstable_opts = true;
968+
}
969+
if noprelude {
970+
opts.push("noprelude");
971+
*unstable_opts = true;
972+
}
973+
if !opts.is_empty() {
974+
value.push(opts.join(","));
975+
value.push(":");
976+
}
977+
value.push(extern_crate_name.as_str());
961978
value.push("=");
962979

963980
let mut pass = |file| {
964981
let mut value = value.clone();
965982
value.push(file);
966-
967-
if current
968-
.pkg
969-
.manifest()
970-
.features()
971-
.require(Feature::public_dependency())
972-
.is_ok()
973-
&& !dep.public
974-
{
975-
cmd.arg("--extern-private");
976-
*need_unstable_opts = true;
977-
} else {
978-
cmd.arg("--extern");
979-
}
980-
981-
cmd.arg(&value);
983+
result.push(OsString::from("--extern"));
984+
result.push(value);
982985
};
983986

984987
let outputs = cx.outputs(&dep.unit)?;
@@ -987,7 +990,7 @@ fn build_deps_args<'a, 'cfg>(
987990
_ => None,
988991
});
989992

990-
if cx.only_requires_rmeta(current, &dep.unit) {
993+
if cx.only_requires_rmeta(unit, &dep.unit) {
991994
let (output, _rmeta) = outputs
992995
.find(|(_output, rmeta)| *rmeta)
993996
.expect("failed to find rlib dep for pipelined dep");
@@ -1000,7 +1003,15 @@ fn build_deps_args<'a, 'cfg>(
10001003
}
10011004
}
10021005
Ok(())
1006+
};
1007+
1008+
for dep in deps {
1009+
if dep.unit.target.linkable() && !dep.unit.mode.is_doc() {
1010+
link_to(&dep, dep.extern_crate_name, dep.noprelude)?;
1011+
}
10031012
}
1013+
1014+
Ok(result)
10041015
}
10051016

10061017
fn envify(s: &str) -> String {

0 commit comments

Comments
 (0)