From 2b7f37b5a22116d902a03ae1661a25cb2d6ff389 Mon Sep 17 00:00:00 2001 From: Lucas Kolstad Date: Tue, 29 Aug 2017 03:43:41 -0700 Subject: [PATCH] Add host dependency path via -L for cargo_test. 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 | 24 +++++++++++++++++ tests/test.rs | 52 ++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/cargo/ops/cargo_test.rs b/src/cargo/ops/cargo_test.rs index 86e431733..d6c1717f8 100644 --- a/src/cargo/ops/cargo_test.rs +++ b/src/cargo/ops/cargo_test.rs @@ -126,6 +126,7 @@ fn run_doc_tests(options: &TestOptions, -> CargoResult<(Test, Vec)> { 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 +} diff --git a/tests/test.rs b/tests/test.rs index 017a39d80..adb89f919 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -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)); +}