From 784d3154cf084e6bbd49200d3e6e71df6c9cdca2 Mon Sep 17 00:00:00 2001 From: Jim McGrath Date: Fri, 5 May 2017 15:57:47 -0500 Subject: [PATCH 1/3] set dylib path correctly for target when running `cargo test` etc --- appveyor.yml | 6 +- src/cargo/ops/cargo_rustc/compilation.rs | 13 +++- src/cargo/ops/cargo_rustc/context.rs | 18 ++++++ src/cargo/util/rustc.rs | 10 ++++ tests/cargotest/lib.rs | 22 +------ tests/cross-compile.rs | 76 ++++++++++++++++++++++++ 6 files changed, 122 insertions(+), 23 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 7c3597b042d..2ed457233b5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -28,7 +28,11 @@ install: - if defined MINGW_URL 7z x -y %MINGW_ARCHIVE% > nul - if defined MINGW_URL set PATH=%CD%\%MINGW_DIR%\bin;C:\msys64\usr\bin;%PATH% - - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe + # FIXME(#3394) use master rustup + # for the purposes of testing this PR, use rustup 1.2.0 because there is possibly a + # change https://github.com/rust-lang-nursery/rustup.rs/pull/1093 about to land + # nightly rustup that will also fix some of the failing windows tests. + - curl -sSfO https://static.rust-lang.org/rustup/archive/1.2.0/x86_64-pc-windows-msvc/rustup-init.exe - rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly-2017-03-03 - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin - if NOT "%TARGET%" == "x86_64-pc-windows-msvc" rustup target add %TARGET% diff --git a/src/cargo/ops/cargo_rustc/compilation.rs b/src/cargo/ops/cargo_rustc/compilation.rs index 5192d2cadb8..cbdb29baa93 100644 --- a/src/cargo/ops/cargo_rustc/compilation.rs +++ b/src/cargo/ops/cargo_rustc/compilation.rs @@ -35,6 +35,12 @@ pub struct Compilation<'cfg> { /// which have dynamic dependencies. pub plugins_dylib_path: PathBuf, + /// The path to rustc's own libstd + pub host_dylib_path: Option, + + /// The path to libstd for the target + pub target_dylib_path: Option, + /// Extra environment variables that were passed to compilations and should /// be passed to future invocations of programs. pub extra_env: HashMap>, @@ -57,6 +63,8 @@ impl<'cfg> Compilation<'cfg> { root_output: PathBuf::from("/"), deps_output: PathBuf::from("/"), plugins_dylib_path: PathBuf::from("/"), + host_dylib_path: None, + target_dylib_path: None, tests: Vec::new(), binaries: Vec::new(), extra_env: HashMap::new(), @@ -98,7 +106,9 @@ impl<'cfg> Compilation<'cfg> { -> CargoResult { let mut search_path = if is_host { - vec![self.plugins_dylib_path.clone()] + let mut search_path = vec![self.plugins_dylib_path.clone()]; + search_path.push(self.host_dylib_path.iter().collect()); + search_path } else { let mut search_path = vec![]; @@ -128,6 +138,7 @@ impl<'cfg> Compilation<'cfg> { } search_path.push(self.root_output.clone()); search_path.push(self.deps_output.clone()); + search_path.push(self.target_dylib_path.iter().collect()); search_path }; diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index 27cd369ba6d..1310ae189f8 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -243,6 +243,24 @@ impl<'a, 'cfg> Context<'a, 'cfg> { None }; + if let Some(ref sysroot) = self.config.rustc()?.sysroot { + let mut rustlib = sysroot.clone(); + if kind == Kind::Host { + if cfg!(windows) { + rustlib.push("bin"); + } else { + rustlib.push("lib"); + } + self.compilation.host_dylib_path = Some(rustlib); + } else { + rustlib.push("lib"); + rustlib.push("rustlib"); + rustlib.push(self.target_triple()); + rustlib.push("lib"); + self.compilation.target_dylib_path = Some(rustlib); + } + }; + let info = match kind { Kind::Target => &mut self.target_info, Kind::Host => &mut self.host_info, diff --git a/src/cargo/util/rustc.rs b/src/cargo/util/rustc.rs index d401452d712..cd2c5510430 100644 --- a/src/cargo/util/rustc.rs +++ b/src/cargo/util/rustc.rs @@ -7,6 +7,7 @@ pub struct Rustc { pub wrapper: Option, pub verbose_version: String, pub host: String, + pub sysroot: Option, } impl Rustc { @@ -35,11 +36,20 @@ impl Rustc { triple.to_string() }; + let sysroot = { + let mut cmd = util::process(&path); + cmd.arg("--print=sysroot"); + cmd.exec_with_output().ok() + .and_then(|output| String::from_utf8(output.stdout).ok() ) + .map(|s| PathBuf::from(s.trim())) + }; + Ok(Rustc { path: path, wrapper: wrapper, verbose_version: verbose_version, host: host, + sysroot: sysroot }) } diff --git a/tests/cargotest/lib.rs b/tests/cargotest/lib.rs index 8446fa829ea..e8497285df1 100644 --- a/tests/cargotest/lib.rs +++ b/tests/cargotest/lib.rs @@ -20,10 +20,9 @@ extern crate url; use std::ffi::OsStr; use std::time::Duration; -use std::path::{Path, PathBuf}; use cargo::util::Rustc; -use cargo::util::paths; +use std::path::PathBuf; pub mod support; pub mod install; @@ -67,25 +66,6 @@ fn _process(t: &OsStr) -> cargo::util::ProcessBuilder { .env_remove("GIT_COMMITTER_EMAIL") .env_remove("CARGO_TARGET_DIR") // we assume 'target' .env_remove("MSYSTEM"); // assume cmd.exe everywhere on windows - - // We'll need dynamic libraries at some point in this test suite, so ensure - // that the rustc libdir is somewhere in LD_LIBRARY_PATH as appropriate. - let mut rustc = RUSTC.with(|r| r.process()); - let output = rustc.arg("--print").arg("sysroot").exec_with_output().unwrap(); - let libdir = String::from_utf8(output.stdout).unwrap(); - let libdir = Path::new(libdir.trim()); - let libdir = if cfg!(windows) { - libdir.join("bin") - } else { - libdir.join("lib") - }; - let mut paths = paths::dylib_path(); - println!("libdir: {:?}", libdir); - if !paths.contains(&libdir) { - paths.push(libdir); - p.env(paths::dylib_path_envvar(), - paths::join_paths(&paths, paths::dylib_path_envvar()).unwrap()); - } return p } diff --git a/tests/cross-compile.rs b/tests/cross-compile.rs index 03dee05491c..d4c134fc3e0 100644 --- a/tests/cross-compile.rs +++ b/tests/cross-compile.rs @@ -1053,3 +1053,79 @@ fn platform_specific_variables_reflected_in_build_scripts() { assert_that(p.cargo("build").arg("-v").arg("--target").arg(&target), execs().with_status(0)); } + +#[test] +fn cross_test_dylib() { + if disabled() { return } + + let target = alternate(); + + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [lib] + name = "foo" + crate_type = ["dylib"] + + [dependencies.bar] + path = "bar" + "#) + .file("src/lib.rs", r#" + extern crate bar as the_bar; + + pub fn bar() { the_bar::baz(); } + + #[test] + fn foo() { bar(); } + "#) + .file("tests/test.rs", r#" + extern crate foo as the_foo; + + #[test] + fn foo() { the_foo::bar(); } + "#) + .file("bar/Cargo.toml", r#" + [package] + name = "bar" + version = "0.0.1" + authors = [] + + [lib] + name = "bar" + crate_type = ["dylib"] + "#) + .file("bar/src/lib.rs", &format!(r#" + use std::env; + pub fn baz() {{ + assert_eq!(env::consts::ARCH, "{}"); + }} + "#, alternate_arch())); + + assert_that(p.cargo_process("test").arg("--target").arg(&target), + execs().with_status(0) + .with_stderr(&format!("\ +[COMPILING] bar v0.0.1 ({dir}/bar) +[COMPILING] foo v0.0.1 ({dir}) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +[RUNNING] target[/]{arch}[/]debug[/]deps[/]foo-[..][EXE] +[RUNNING] target[/]{arch}[/]debug[/]deps[/]test-[..][EXE]", + dir = p.url(), arch = alternate())) + .with_stdout(" +running 1 test +test foo ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured + + +running 1 test +test foo ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured + +")); + +} From b1a96167846c90fb80a5335764d6e1a302c58a4e Mon Sep 17 00:00:00 2001 From: Jim McGrath Date: Mon, 8 May 2017 12:57:29 -0500 Subject: [PATCH 2/3] avoid an extra cargo invocation --- src/cargo/ops/cargo_rustc/context.rs | 26 ++++++++++++++++---------- src/cargo/util/rustc.rs | 10 ---------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index 1310ae189f8..865d4bbc078 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -196,11 +196,12 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } let mut with_cfg = process.clone(); + with_cfg.arg("--print=sysroot"); with_cfg.arg("--print=cfg"); - let mut has_cfg = true; + let mut has_cfg_and_sysroot = true; let output = with_cfg.exec_with_output().or_else(|_| { - has_cfg = false; + has_cfg_and_sysroot = false; process.exec_with_output() }).chain_error(|| { human(format!("failed to run `rustc` to learn about \ @@ -237,14 +238,13 @@ impl<'a, 'cfg> Context<'a, 'cfg> { map.insert(crate_type.to_string(), Some((prefix.to_string(), suffix.to_string()))); } - let cfg = if has_cfg { - Some(try!(lines.map(Cfg::from_str).collect())) - } else { - None - }; - - if let Some(ref sysroot) = self.config.rustc()?.sysroot { - let mut rustlib = sysroot.clone(); + if has_cfg_and_sysroot { + let line = match lines.next() { + Some(line) => line, + None => bail!("output of --print=sysroot missing when learning about \ + target-specific information from rustc"), + }; + let mut rustlib = PathBuf::from(line); if kind == Kind::Host { if cfg!(windows) { rustlib.push("bin"); @@ -259,6 +259,12 @@ impl<'a, 'cfg> Context<'a, 'cfg> { rustlib.push("lib"); self.compilation.target_dylib_path = Some(rustlib); } + } + + let cfg = if has_cfg_and_sysroot { + Some(try!(lines.map(Cfg::from_str).collect())) + } else { + None }; let info = match kind { diff --git a/src/cargo/util/rustc.rs b/src/cargo/util/rustc.rs index cd2c5510430..d401452d712 100644 --- a/src/cargo/util/rustc.rs +++ b/src/cargo/util/rustc.rs @@ -7,7 +7,6 @@ pub struct Rustc { pub wrapper: Option, pub verbose_version: String, pub host: String, - pub sysroot: Option, } impl Rustc { @@ -36,20 +35,11 @@ impl Rustc { triple.to_string() }; - let sysroot = { - let mut cmd = util::process(&path); - cmd.arg("--print=sysroot"); - cmd.exec_with_output().ok() - .and_then(|output| String::from_utf8(output.stdout).ok() ) - .map(|s| PathBuf::from(s.trim())) - }; - Ok(Rustc { path: path, wrapper: wrapper, verbose_version: verbose_version, host: host, - sysroot: sysroot }) } From d773d7bb9391f1bdab442a070235ac2acb4adbb3 Mon Sep 17 00:00:00 2001 From: Jim McGrath Date: Mon, 8 May 2017 12:58:02 -0500 Subject: [PATCH 3/3] use latest rustup again (undo pin to 1.2.0) --- appveyor.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 2ed457233b5..7c3597b042d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -28,11 +28,7 @@ install: - if defined MINGW_URL 7z x -y %MINGW_ARCHIVE% > nul - if defined MINGW_URL set PATH=%CD%\%MINGW_DIR%\bin;C:\msys64\usr\bin;%PATH% - # FIXME(#3394) use master rustup - # for the purposes of testing this PR, use rustup 1.2.0 because there is possibly a - # change https://github.com/rust-lang-nursery/rustup.rs/pull/1093 about to land - # nightly rustup that will also fix some of the failing windows tests. - - curl -sSfO https://static.rust-lang.org/rustup/archive/1.2.0/x86_64-pc-windows-msvc/rustup-init.exe + - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe - rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly-2017-03-03 - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin - if NOT "%TARGET%" == "x86_64-pc-windows-msvc" rustup target add %TARGET%