diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index bec0be93e3f..74cc8949aae 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -24,7 +24,7 @@ use std::collections::{HashMap, HashSet}; use std::default::Default; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::sync::Arc; use core::{Package, Source, Target}; @@ -32,7 +32,7 @@ use core::{PackageId, PackageIdSpec, Profile, Profiles, TargetKind, Workspace}; use core::resolver::{Method, Resolve}; use ops::{self, BuildOutput, DefaultExecutor, Executor}; use util::config::Config; -use util::{profile, CargoResult}; +use util::{profile, CargoResult, CargoResultExt}; /// Contains information about how a package should be compiled. #[derive(Debug)] @@ -235,7 +235,17 @@ pub fn compile_ws<'a>( ref target_rustc_args, } = *options; - let target = target.clone(); + let target = match target { + &Some(ref target) if target.ends_with(".json") => { + let path = Path::new(target) + .canonicalize() + .chain_err(|| format_err!("Target path {:?} is not a valid file", target))?; + Some(path.into_os_string() + .into_string() + .map_err(|_| format_err!("Target path is not valid unicode"))?) + } + other => other.clone(), + }; if jobs == Some(0) { bail!("jobs must be at least 1") diff --git a/tests/testsuite/custom_target.rs b/tests/testsuite/custom_target.rs new file mode 100644 index 00000000000..86f5b954236 --- /dev/null +++ b/tests/testsuite/custom_target.rs @@ -0,0 +1,170 @@ +use cargotest::is_nightly; +use cargotest::support::{execs, project}; +use hamcrest::assert_that; + +#[test] +fn custom_target_minimal() { + if !is_nightly() { + return; + } + let p = project("foo") + .file( + "Cargo.toml", + r#" + [package] + + name = "foo" + version = "0.0.1" + authors = ["author@example.com"] + "#, + ) + .file( + "src/lib.rs", + r#" + #![feature(no_core)] + #![feature(lang_items)] + #![no_core] + + pub fn foo() -> u32 { + 42 + } + + #[lang = "sized"] + pub trait Sized { + // Empty. + } + #[lang = "copy"] + pub trait Copy { + // Empty. + } + "#, + ) + .file( + "custom-target.json", + r#" + { + "llvm-target": "x86_64-unknown-none-gnu", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "linker-flavor": "ld.lld" + } + "#, + ) + .build(); + + assert_that( + p.cargo("build") + .arg("--lib") + .arg("--target") + .arg("custom-target.json") + .arg("-v"), + execs().with_status(0), + ); + assert_that( + p.cargo("build") + .arg("--lib") + .arg("--target") + .arg("src/../custom-target.json") + .arg("-v"), + execs().with_status(0), + ); +} + +#[test] +fn custom_target_dependency() { + if !is_nightly() { + return; + } + let p = project("foo") + .file( + "Cargo.toml", + r#" + [package] + + name = "foo" + version = "0.0.1" + authors = ["author@example.com"] + + [dependencies] + bar = { path = "bar" } + "#, + ) + .file( + "src/lib.rs", + r#" + #![feature(no_core)] + #![feature(lang_items)] + #![feature(optin_builtin_traits)] + #![no_core] + + extern crate bar; + + pub fn foo() -> u32 { + bar::bar() + } + + #[lang = "freeze"] + unsafe auto trait Freeze {} + "#, + ) + .file( + "bar/Cargo.toml", + r#" + [package] + + name = "bar" + version = "0.0.1" + authors = ["author@example.com"] + "#, + ) + .file( + "bar/src/lib.rs", + r#" + #![feature(no_core)] + #![feature(lang_items)] + #![no_core] + + pub fn bar() -> u32 { + 42 + } + + #[lang = "sized"] + pub trait Sized { + // Empty. + } + #[lang = "copy"] + pub trait Copy { + // Empty. + } + "#, + ) + .file( + "custom-target.json", + r#" + { + "llvm-target": "x86_64-unknown-none-gnu", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "linker-flavor": "ld.lld" + } + "#, + ) + .build(); + + assert_that( + p.cargo("build") + .arg("--lib") + .arg("--target") + .arg("custom-target.json") + .arg("-v"), + execs().with_status(0), + ); +} diff --git a/tests/testsuite/main.rs b/tests/testsuite/main.rs index bd7c32b9af0..979afe3b720 100644 --- a/tests/testsuite/main.rs +++ b/tests/testsuite/main.rs @@ -43,6 +43,7 @@ mod config; mod corrupt_git; mod cross_compile; mod cross_publish; +mod custom_target; mod death; mod dep_info; mod directory;