Skip to content

Commit

Permalink
set dylib path correctly for target when running cargo test etc
Browse files Browse the repository at this point in the history
  • Loading branch information
mcgoo committed May 8, 2017
1 parent 20a085e commit 784d315
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 23 deletions.
6 changes: 5 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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%
Expand Down
13 changes: 12 additions & 1 deletion src/cargo/ops/cargo_rustc/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<PathBuf>,

/// The path to libstd for the target
pub target_dylib_path: Option<PathBuf>,

/// Extra environment variables that were passed to compilations and should
/// be passed to future invocations of programs.
pub extra_env: HashMap<PackageId, Vec<(String, String)>>,
Expand All @@ -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(),
Expand Down Expand Up @@ -98,7 +106,9 @@ impl<'cfg> Compilation<'cfg> {
-> CargoResult<ProcessBuilder> {

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![];

Expand Down Expand Up @@ -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
};

Expand Down
18 changes: 18 additions & 0 deletions src/cargo/ops/cargo_rustc/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
10 changes: 10 additions & 0 deletions src/cargo/util/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub struct Rustc {
pub wrapper: Option<PathBuf>,
pub verbose_version: String,
pub host: String,
pub sysroot: Option<PathBuf>,
}

impl Rustc {
Expand Down Expand Up @@ -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
})
}

Expand Down
22 changes: 1 addition & 21 deletions tests/cargotest/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
}

Expand Down
76 changes: 76 additions & 0 deletions tests/cross-compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
"));

}

0 comments on commit 784d315

Please sign in to comment.