]> git.proxmox.com Git - cargo.git/commitdiff
Fix cross compiling with a build script
authorAlex Crichton <alex@alexcrichton.com>
Fri, 7 Nov 2014 17:25:25 +0000 (09:25 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 7 Nov 2014 17:25:25 +0000 (09:25 -0800)
Previously there was a mixup of where the build script was getting compiled into
as well as where the output was going to. This commit fixes the problems for
now, but still has room for improvement in the future.

Build scripts themselves are now unconditionally built into `target/build/..`
because they're compiled for the host platform. Their outputs are in
`target/$target/build/..` as expected.

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

index c11c64f6bbf9a1f8b4761207316fe0de3b796e5d..e5d3d78595561f1c3b839ce734334cc9562cca01 100644 (file)
@@ -10,7 +10,7 @@ use util::{CargoResult, CargoError, human};
 use util::{internal, ChainError, Require};
 
 use super::job::Work;
-use super::{fingerprint, process, KindHost, Context};
+use super::{fingerprint, process, KindTarget, KindHost, Context};
 use util::Freshness;
 
 /// Contains the parsed output of a custom build script.
@@ -31,12 +31,15 @@ pub struct BuildState {
 /// Prepares a `Work` that executes the target as a custom build script.
 pub fn prepare(pkg: &Package, target: &Target, cx: &mut Context)
                -> CargoResult<(Work, Work, Freshness)> {
+    // TODO: this shouldn't explicitly pass `KindTarget` for the layout, we
+    //       may be running a build script for a plugin dependency.
     let (script_output, old_script_output, build_output, old_build_output) = {
-        let layout = cx.layout(pkg, KindHost);
-        (layout.build(pkg),
-         layout.proxy().old_build(pkg),
-         layout.build_out(pkg),
-         layout.proxy().old_build(pkg).join("out"))
+        let target = cx.layout(pkg, KindTarget);
+        let host = cx.layout(pkg, KindHost);
+        (host.build(pkg),
+         host.proxy().old_build(pkg),
+         target.build_out(pkg),
+         target.proxy().old_build(pkg).join("out"))
     };
 
     // Building the command to execute
@@ -92,7 +95,8 @@ pub fn prepare(pkg: &Package, target: &Target, cx: &mut Context)
                script_output.clone(), old_build_output.clone(),
                build_output.clone());
 
-    try!(fs::mkdir(&script_output, USER_RWX));
+    try!(fs::mkdir_recursive(&cx.layout(pkg, KindTarget).build(pkg), USER_RWX));
+    try!(fs::mkdir_recursive(&cx.layout(pkg, KindHost).build(pkg), USER_RWX));
 
     // Prepare the unit of "dirty work" which will actually run the custom build
     // command.
index cc5745b0dca48733634449395a1dcd0d4044f44f..57ed1418c1fe38b438c70ffbe72957dce7d2fe4f 100644 (file)
@@ -474,3 +474,45 @@ test!(cross_but_no_dylibs {
                        .with_stderr("dylib outputs are not supported for \
                                      arm-apple-ios"));
 })
+
+test!(cross_with_a_build_script {
+    if disabled() { return }
+
+    let target = alternate();
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.0"
+            authors = []
+            build = 'build.rs'
+        "#)
+        .file("build.rs", format!(r#"
+            use std::os;
+            fn main() {{
+                assert_eq!(os::getenv("TARGET").unwrap().as_slice(), "{0}");
+                let mut path = Path::new(os::getenv("OUT_DIR").unwrap());
+                assert_eq!(path.filename().unwrap(), b"out");
+                path.pop();
+                assert!(path.filename().unwrap().starts_with(b"foo-"));
+                path.pop();
+                assert_eq!(path.filename().unwrap(), b"build");
+                path.pop();
+                assert_eq!(path.filename().unwrap(), b"{0}");
+                path.pop();
+                assert_eq!(path.filename().unwrap(), b"target");
+            }}
+        "#, target).as_slice())
+        .file("src/main.rs", "fn main() {}");
+
+    assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
+                execs().with_status(0)
+                       .with_stdout(format!("\
+{compiling} foo v0.0.0 (file://[..])
+{running} `rustc build.rs [..] --out-dir {dir}{sep}target{sep}build{sep}foo-[..]`
+{running} `{dir}{sep}target{sep}build{sep}foo-[..]build-script-build`
+{running} `rustc {dir}{sep}src{sep}main.rs [..] --target {target} [..]`
+", compiling = COMPILING, running = RUNNING, target = target,
+   dir = p.root().display(), sep = path::SEP).as_slice()));
+})
+