Skip to content

Commit 80f19a8

Browse files
committed
Auto merge of #4006 - mcgoo:cargo_test_dylib, r=alexcrichton
fix `cargo test` of dylib projects for end user runs too Fixes running `cargo test` and `cargo test --target <target>` for dylib projects. Moves the logic just landed in #3996 into cargo itself, so cargo sets the dylib path for anyone running `cargo test` or `cargo run`. Current master sets the dylib path only for `cargo test` on cargo itself. This PR pins to rustup 1.2.0 for the purposes of testing. If rust-lang/rustup#1093 ends up working out, then this PR would only be important for non-rustup users and people doing cross testing, `cargo test --target <target>`. Arguably https://github.com/mcgoo/cargo/blob/ed273851f8bc76f726eda4a2e2a7bb470c3718bc/src/cargo/ops/cargo_rustc/context.rs#L249-L253 should point to lib/rustlib/\<host triple\>/lib instead of sysroot/lib, because I think if the libs are different, you will never be able to compile a working plugin anyway, and for the host=target case you get the lib/rustlib/\<host triple\>/lib anyhow. Is there ever a case where the lib/rustlib/\<host triple\>/lib and sysroot/lib versions of the libs would be expected to differ? This is not a huge deal for me one way or the other - it doesn't impact my workflow at all. I nearly dropped it when I saw @alexcrichton had made it all work in 3996, but I think it's worth doing because it removes a surprise. It certainly would have saved me a couple of days of confusion. Either way, thanks for looking it over.
2 parents cf17c9f + d773d7b commit 80f19a8

File tree

4 files changed

+116
-25
lines changed

4 files changed

+116
-25
lines changed

src/cargo/ops/cargo_rustc/compilation.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ pub struct Compilation<'cfg> {
3535
/// which have dynamic dependencies.
3636
pub plugins_dylib_path: PathBuf,
3737

38+
/// The path to rustc's own libstd
39+
pub host_dylib_path: Option<PathBuf>,
40+
41+
/// The path to libstd for the target
42+
pub target_dylib_path: Option<PathBuf>,
43+
3844
/// Extra environment variables that were passed to compilations and should
3945
/// be passed to future invocations of programs.
4046
pub extra_env: HashMap<PackageId, Vec<(String, String)>>,
@@ -57,6 +63,8 @@ impl<'cfg> Compilation<'cfg> {
5763
root_output: PathBuf::from("/"),
5864
deps_output: PathBuf::from("/"),
5965
plugins_dylib_path: PathBuf::from("/"),
66+
host_dylib_path: None,
67+
target_dylib_path: None,
6068
tests: Vec::new(),
6169
binaries: Vec::new(),
6270
extra_env: HashMap::new(),
@@ -98,13 +106,16 @@ impl<'cfg> Compilation<'cfg> {
98106
-> CargoResult<ProcessBuilder> {
99107

100108
let mut search_path = if is_host {
101-
vec![self.plugins_dylib_path.clone()]
109+
let mut search_path = vec![self.plugins_dylib_path.clone()];
110+
search_path.push(self.host_dylib_path.iter().collect());
111+
search_path
102112
} else {
103113
let mut search_path =
104114
super::filter_dynamic_search_path(self.native_dirs.iter(),
105115
&self.root_output);
106116
search_path.push(self.root_output.clone());
107117
search_path.push(self.deps_output.clone());
118+
search_path.push(self.target_dylib_path.iter().collect());
108119
search_path
109120
};
110121

src/cargo/ops/cargo_rustc/context.rs

+27-3
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,12 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
206206
}
207207

208208
let mut with_cfg = process.clone();
209+
with_cfg.arg("--print=sysroot");
209210
with_cfg.arg("--print=cfg");
210211

211-
let mut has_cfg = true;
212+
let mut has_cfg_and_sysroot = true;
212213
let output = with_cfg.exec_with_output().or_else(|_| {
213-
has_cfg = false;
214+
has_cfg_and_sysroot = false;
214215
process.exec_with_output()
215216
}).chain_error(|| {
216217
human(format!("failed to run `rustc` to learn about \
@@ -247,7 +248,30 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
247248
map.insert(crate_type.to_string(), Some((prefix.to_string(), suffix.to_string())));
248249
}
249250

250-
let cfg = if has_cfg {
251+
if has_cfg_and_sysroot {
252+
let line = match lines.next() {
253+
Some(line) => line,
254+
None => bail!("output of --print=sysroot missing when learning about \
255+
target-specific information from rustc"),
256+
};
257+
let mut rustlib = PathBuf::from(line);
258+
if kind == Kind::Host {
259+
if cfg!(windows) {
260+
rustlib.push("bin");
261+
} else {
262+
rustlib.push("lib");
263+
}
264+
self.compilation.host_dylib_path = Some(rustlib);
265+
} else {
266+
rustlib.push("lib");
267+
rustlib.push("rustlib");
268+
rustlib.push(self.target_triple());
269+
rustlib.push("lib");
270+
self.compilation.target_dylib_path = Some(rustlib);
271+
}
272+
}
273+
274+
let cfg = if has_cfg_and_sysroot {
251275
Some(try!(lines.map(Cfg::from_str).collect()))
252276
} else {
253277
None

tests/cargotest/lib.rs

+1-21
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,9 @@ extern crate url;
2020

2121
use std::ffi::OsStr;
2222
use std::time::Duration;
23-
use std::path::{Path, PathBuf};
2423

2524
use cargo::util::Rustc;
26-
use cargo::util::paths;
25+
use std::path::PathBuf;
2726

2827
pub mod support;
2928
pub mod install;
@@ -67,25 +66,6 @@ fn _process(t: &OsStr) -> cargo::util::ProcessBuilder {
6766
.env_remove("GIT_COMMITTER_EMAIL")
6867
.env_remove("CARGO_TARGET_DIR") // we assume 'target'
6968
.env_remove("MSYSTEM"); // assume cmd.exe everywhere on windows
70-
71-
// We'll need dynamic libraries at some point in this test suite, so ensure
72-
// that the rustc libdir is somewhere in LD_LIBRARY_PATH as appropriate.
73-
let mut rustc = RUSTC.with(|r| r.process());
74-
let output = rustc.arg("--print").arg("sysroot").exec_with_output().unwrap();
75-
let libdir = String::from_utf8(output.stdout).unwrap();
76-
let libdir = Path::new(libdir.trim());
77-
let libdir = if cfg!(windows) {
78-
libdir.join("bin")
79-
} else {
80-
libdir.join("lib")
81-
};
82-
let mut paths = paths::dylib_path();
83-
println!("libdir: {:?}", libdir);
84-
if !paths.contains(&libdir) {
85-
paths.push(libdir);
86-
p.env(paths::dylib_path_envvar(),
87-
paths::join_paths(&paths, paths::dylib_path_envvar()).unwrap());
88-
}
8969
return p
9070
}
9171

tests/cross-compile.rs

+76
Original file line numberDiff line numberDiff line change
@@ -1053,3 +1053,79 @@ fn platform_specific_variables_reflected_in_build_scripts() {
10531053
assert_that(p.cargo("build").arg("-v").arg("--target").arg(&target),
10541054
execs().with_status(0));
10551055
}
1056+
1057+
#[test]
1058+
fn cross_test_dylib() {
1059+
if disabled() { return }
1060+
1061+
let target = alternate();
1062+
1063+
let p = project("foo")
1064+
.file("Cargo.toml", r#"
1065+
[package]
1066+
name = "foo"
1067+
version = "0.0.1"
1068+
authors = []
1069+
1070+
[lib]
1071+
name = "foo"
1072+
crate_type = ["dylib"]
1073+
1074+
[dependencies.bar]
1075+
path = "bar"
1076+
"#)
1077+
.file("src/lib.rs", r#"
1078+
extern crate bar as the_bar;
1079+
1080+
pub fn bar() { the_bar::baz(); }
1081+
1082+
#[test]
1083+
fn foo() { bar(); }
1084+
"#)
1085+
.file("tests/test.rs", r#"
1086+
extern crate foo as the_foo;
1087+
1088+
#[test]
1089+
fn foo() { the_foo::bar(); }
1090+
"#)
1091+
.file("bar/Cargo.toml", r#"
1092+
[package]
1093+
name = "bar"
1094+
version = "0.0.1"
1095+
authors = []
1096+
1097+
[lib]
1098+
name = "bar"
1099+
crate_type = ["dylib"]
1100+
"#)
1101+
.file("bar/src/lib.rs", &format!(r#"
1102+
use std::env;
1103+
pub fn baz() {{
1104+
assert_eq!(env::consts::ARCH, "{}");
1105+
}}
1106+
"#, alternate_arch()));
1107+
1108+
assert_that(p.cargo_process("test").arg("--target").arg(&target),
1109+
execs().with_status(0)
1110+
.with_stderr(&format!("\
1111+
[COMPILING] bar v0.0.1 ({dir}/bar)
1112+
[COMPILING] foo v0.0.1 ({dir})
1113+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1114+
[RUNNING] target[/]{arch}[/]debug[/]deps[/]foo-[..][EXE]
1115+
[RUNNING] target[/]{arch}[/]debug[/]deps[/]test-[..][EXE]",
1116+
dir = p.url(), arch = alternate()))
1117+
.with_stdout("
1118+
running 1 test
1119+
test foo ... ok
1120+
1121+
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
1122+
1123+
1124+
running 1 test
1125+
test foo ... ok
1126+
1127+
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
1128+
1129+
"));
1130+
1131+
}

0 commit comments

Comments
 (0)