Add host dependency path via -L for cargo_test.
authorLucas Kolstad <lkolstad@uw.edu>
Tue, 29 Aug 2017 10:43:41 +0000 (03:43 -0700)
committerLucas Kolstad <lkolstad@uw.edu>
Tue, 29 Aug 2017 11:18:32 +0000 (04:18 -0700)
Proc-macro crates' dependencies in the host dependency directory cannot
be found when running `cargo test` with the `--target {target}` flag
set. This adds the host dependency directory with -L when building tests
and a test case that fails before and passes after this patch.

A new function find_host_deps(..) is added to accomplish this which can
determine the path of the host dependencies directory from within
run_doc_tests(..) where the missing library search path is needed.

Fixes #4224
Fixes #4254

src/cargo/ops/cargo_test.rs
tests/test.rs

index 86e4317330211f3ccbf86bd4c3d57bf67490fecd..d6c1717f86138e95ef9f09dc8fdfc2164c1d0b43 100644 (file)
@@ -126,6 +126,7 @@ fn run_doc_tests(options: &TestOptions,
                  -> CargoResult<(Test, Vec<ProcessError>)> {
     let mut errors = Vec::new();
     let config = options.compile_opts.config;
+    let host_deps = find_host_deps(options, compilation);
 
     // We don't build/rust doctests if target != host
     if config.rustc()?.host != compilation.target {
@@ -144,6 +145,8 @@ fn run_doc_tests(options: &TestOptions,
             p.arg("--test").arg(lib)
              .arg("--crate-name").arg(&crate_name);
 
+            p.arg("-L").arg(&host_deps);
+
             for &rust_dep in &[&compilation.deps_output] {
                 let mut arg = OsString::from("dependency=");
                 arg.push(rust_dep);
@@ -198,3 +201,24 @@ fn run_doc_tests(options: &TestOptions,
     }
     Ok((Test::Doc, errors))
 }
+
+fn find_host_deps(options: &TestOptions, compilation: &Compilation) -> OsString {
+    let build_type = if options.compile_opts.release { "release" } else { "debug" };
+    let mut dir = compilation.root_output.clone();
+
+    // first pop off the build_type
+    dir.pop();
+    // if we see the target next, pop it off
+    let target: &OsStr = compilation.target.as_ref();
+    if dir.file_name().unwrap() == target {
+        dir.pop();
+    }
+    // push the build_type back on
+    dir.push(build_type);
+    // and we are looking for the deps directory
+    dir.push("deps");
+
+    let mut host_deps = OsString::from("dependency=");
+    host_deps.push(dir);
+    host_deps
+}
index 017a39d80931a5dd3ab98ecaa53107577c473a3b..adb89f9190a01057a4dd2322238348bc18926cc8 100644 (file)
@@ -6,7 +6,7 @@ use std::fs::File;
 use std::io::prelude::*;
 use std::str;
 
-use cargotest::{sleep_ms, is_nightly};
+use cargotest::{sleep_ms, is_nightly, rustc_host};
 use cargotest::support::{project, execs, basic_bin_manifest, basic_lib_manifest, cargo_exe};
 use cargotest::support::paths::CargoPathExt;
 use cargotest::support::registry::Package;
@@ -2782,3 +2782,53 @@ fn publish_a_crate_without_tests() {
     assert_that(p.cargo("test").arg("--package").arg("testless"),
                 execs().with_status(0));
 }
+
+#[test]
+fn find_dependency_of_proc_macro_dependency_with_target() {
+    let workspace = project("workspace")
+        .file("Cargo.toml", r#"
+            [workspace]
+            members = ["root", "proc_macro_dep"]
+        "#)
+        .file("root/Cargo.toml", r#"
+            [project]
+            name = "root"
+            version = "0.1.0"
+            authors = []
+
+            [dependencies]
+            proc_macro_dep = { path = "../proc_macro_dep" }
+        "#)
+        .file("root/src/lib.rs", r#"
+            #[macro_use]
+            extern crate proc_macro_dep;
+
+            #[derive(Noop)]
+            pub struct X;
+        "#)
+        .file("proc_macro_dep/Cargo.toml", r#"
+            [project]
+            name = "proc_macro_dep"
+            version = "0.1.0"
+            authors = []
+
+            [lib]
+            proc-macro = true
+
+            [dependencies]
+            base64 = "^0.6"
+        "#)
+        .file("proc_macro_dep/src/lib.rs", r#"
+            extern crate base64;
+            extern crate proc_macro;
+            use proc_macro::TokenStream;
+
+            #[proc_macro_derive(Noop)]
+            pub fn noop(_input: TokenStream) -> TokenStream {
+                "".parse().unwrap()
+            }
+        "#);
+        workspace.build();
+    assert_that(workspace.cargo("test").arg("--all").arg("--target").arg(rustc_host()),
+                execs().with_status(0));
+}