]> git.proxmox.com Git - cargo.git/commitdiff
Fix some dep errors with cross-compiled plugins
authorAlex Crichton <alex@alexcrichton.com>
Tue, 29 Jul 2014 00:08:46 +0000 (17:08 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 29 Jul 2014 00:08:46 +0000 (17:08 -0700)
* Make sure plugins link to plugin dependencies, not target dependencies.
  Previously the --extern flag was being passed incorrectly but the dependency
  was being picked up by -L anyway.

* Fix a type and actually put the host dep directory into LD_LIBRARY_PATH, not
  the target directory. A test was added for this change.

src/cargo/ops/cargo_rustc/mod.rs
tests/test_cargo_cross_compile.rs

index 9c5535b155f45ad1f3e1b34d5e011d3113b8bce8..1b94648d8cca980697c13c8f05c867f9d3d7d42b 100644 (file)
@@ -335,6 +335,8 @@ fn build_plugin_args(mut cmd: ProcessBuilder, cx: &Context,
 
 fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package,
                    cx: &Context, plugin: bool) -> ProcessBuilder {
+    enum LinkReason { Dependency, LocalLib }
+
     let layout = cx.layout(plugin);
     cmd = cmd.arg("-L").arg(layout.root());
     cmd = cmd.arg("-L").arg(layout.deps());
@@ -344,7 +346,7 @@ fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package,
     cmd = push_native_dirs(cmd, &layout, package, cx, &mut HashSet::new());
 
     for &(_, target) in cx.dep_targets(package).iter() {
-        cmd = link_to(cmd, target, cx, true);
+        cmd = link_to(cmd, target, cx, plugin, Dependency);
     }
 
     let mut targets = package.get_targets().iter().filter(|target| {
@@ -353,23 +355,26 @@ fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package,
 
     if target.is_bin() {
         for target in targets {
-            cmd = link_to(cmd, target, cx, false);
+            cmd = link_to(cmd, target, cx, plugin, LocalLib);
         }
     }
 
     return cmd;
 
     fn link_to(mut cmd: ProcessBuilder, target: &Target,
-               cx: &Context, is_dep_lib: bool) -> ProcessBuilder {
-        let layout = cx.layout(target.get_profile().is_plugin());
+               cx: &Context, plugin: bool, reason: LinkReason) -> ProcessBuilder {
+        // If this target is itself a plugin *or* if it's being linked to a
+        // plugin, then we want the plugin directory. Otherwise we want the
+        // target directory (hence the || here).
+        let layout = cx.layout(plugin || target.get_profile().is_plugin());
+
         for filename in cx.target_filenames(target).iter() {
             let mut v = Vec::new();
             v.push_all(target.get_name().as_bytes());
             v.push(b'=');
-            if is_dep_lib {
-                v.push_all(layout.deps().as_vec());
-            } else {
-                v.push_all(layout.root().as_vec());
+            match reason {
+                Dependency => v.push_all(layout.deps().as_vec()),
+                LocalLib => v.push_all(layout.root().as_vec()),
             }
             v.push(b'/');
             v.push_all(filename.as_bytes());
@@ -403,7 +408,7 @@ pub fn process<T: ToCStr>(cmd: T, pkg: &Package, cx: &Context) -> ProcessBuilder
     // When invoking a tool, we need the *host* deps directory in the dynamic
     // library search path for plugins and such which have dynamic dependencies.
     let mut search_path = DynamicLibrary::search_path();
-    search_path.push(cx.layout(false).deps().clone());
+    search_path.push(cx.layout(true).deps().clone());
     let search_path = os::join_paths(search_path.as_slice()).unwrap();
 
     util::process(cmd)
index e7978e2a13ae8950a849dfef1486d7c4ebd8a847..7e2fe4d7e5534bb7d1f5d8944fd3cfa01eff1de6 100644 (file)
@@ -268,3 +268,67 @@ test!(linker_and_ar {
                             sep = path::SEP,
                             ).as_slice()));
 })
+
+test!(plugin_with_extra_dylib_dep {
+    let foo = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+
+            [dependencies.bar]
+            path = "../bar"
+        "#)
+        .file("src/main.rs", r#"
+            #![feature(phase)]
+            #[phase(plugin)] extern crate bar;
+
+            fn main() {}
+        "#);
+    let bar = project("bar")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "bar"
+            version = "0.0.1"
+            authors = []
+
+            [[lib]]
+            name = "bar"
+            plugin = true
+
+            [dependencies.baz]
+            path = "../baz"
+        "#)
+        .file("src/lib.rs", r#"
+            #![feature(plugin_registrar)]
+
+            extern crate rustc;
+            extern crate baz;
+
+            use rustc::plugin::Registry;
+
+            #[plugin_registrar]
+            pub fn foo(reg: &mut Registry) {
+                println!("{}", baz::baz());
+            }
+        "#);
+    let baz = project("baz")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "baz"
+            version = "0.0.1"
+            authors = []
+
+            [[lib]]
+            name = "baz"
+            crate_type = ["dylib"]
+        "#)
+        .file("src/lib.rs", "pub fn baz() -> int { 1 }");
+    bar.build();
+    baz.build();
+
+    let target = alternate();
+    assert_that(foo.cargo_process("cargo-build").arg("--target").arg(target),
+                execs().with_status(0));
+})