@@ -47,7 +47,6 @@ pub struct Context<'a, 'cfg: 'a> {
target_info: TargetInfo,
host_info: TargetInfo,
profiles: &'a Profiles,
rustflags: Option<String>,
}

#[derive(Clone)]
@@ -80,7 +79,6 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
let engine = build_config.exec_engine.as_ref().cloned().unwrap_or({
Arc::new(Box::new(ProcessEngine))
});
let rustflags = env::var("RUSTFLAGS").ok();
Ok(Context {
target_triple: target_triple,
host: host,
@@ -100,7 +98,6 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
build_scripts: HashMap::new(),
build_explicit_deps: HashMap::new(),
links: Links::new(),
rustflags: rustflags,
})
}

@@ -621,7 +618,9 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
&self.profiles.dev
}

pub fn rustflags_args(&self, unit: &Unit) -> Vec<String> {
// Acquire extra flags to pass to the compiler from the
// RUSTFLAGS environment variable and similar config values
pub fn rustflags_args(&self, unit: &Unit) -> CargoResult<Vec<String>> {
// We *want* to apply RUSTFLAGS only to builds for the
// requested target architecture, and not to things like build
// scripts and plugins, which may be for an entirely different
@@ -643,22 +642,29 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
// RUSTFLAGS.
let compiling_with_target = self.build_config.requested_target.is_some();
let is_target_kind = unit.kind == Kind::Target;
let use_rustflags = match (compiling_with_target, is_target_kind) {
(false, _) => true,
(true, true) => true,
(true, false) => false,
};

if !use_rustflags { return Vec::new(); }
if compiling_with_target && ! is_target_kind {
// This is probably a build script or plugin and we're
// compiling with --target. In this scenario there are
// no rustflags we can apply.
return Ok(Vec::new());
}

let mut args = Vec::new();
// First try RUSTFLAGS from the environment
if let Some(a) = env::var("RUSTFLAGS").ok() {
let args = a.split(" ")
.map(str::trim)
.filter(|s| !s.is_empty())
.map(str::to_string);
return Ok(args.collect());
}

if let Some(ref a) = self.rustflags {
for s in a.split(" ") {
args.push(s.to_owned());
}
// Then the build.rustflags value
if let Some(args) = try!(self.config.get_list("build.rustflags")) {
let args = args.val.into_iter().map(|a| a.0);
return Ok(args.collect());
}

args
Ok(Vec::new())
}
}
@@ -354,7 +354,7 @@ fn calculate<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
deps: deps,
local: local,
memoized_hash: Mutex::new(None),
rustflags: cx.rustflags_args(unit),
rustflags: try!(cx.rustflags_args(unit)),
});
cx.fingerprints.insert(*unit, fingerprint.clone());
Ok(fingerprint)
@@ -243,7 +243,7 @@ fn rustc(cx: &mut Context, unit: &Unit) -> CargoResult<Work> {
let dep_info_loc = fingerprint::dep_info_loc(cx, unit);
let cwd = cx.config.cwd().to_path_buf();

let rustflags = cx.rustflags_args(unit);
let rustflags = try!(cx.rustflags_args(unit));

return Ok(Work::new(move |desc_tx| {
// Only at runtime have we discovered what the extra -L and -l
@@ -2068,381 +2068,3 @@ test!(manifest_with_bom_is_ok {
assert_that(p.cargo_process("build").arg("-v"),
execs().with_status(0));
});

test!(rustflags_normal_source {
let p = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
"#)
.file("src/lib.rs", "")
.file("src/bin/a.rs", "fn main() {}")
.file("examples/b.rs", "fn main() {}")
.file("tests/c.rs", "#[test] fn f() { }")
.file("benches/d.rs", r#"
#![feature(test)]
extern crate test;
#[bench] fn run1(_ben: &mut test::Bencher) { }"#);
p.build();

// Use RUSTFLAGS to pass an argument that will generate an error
assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
.arg("--lib"),
execs().with_status(101));
assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
.arg("--bin=a"),
execs().with_status(101));
assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
.arg("--bin=b"),
execs().with_status(101));
assert_that(p.cargo("check").env("RUSTFLAGS", "-Z bogus"),
execs().with_status(101));
assert_that(p.cargo("bench").env("RUSTFLAGS", "-Z bogus"),
execs().with_status(101));
});

test!(rustflags_build_script {
// RUSTFLAGS should be passed to rustc for build scripts
// when --target is not specified.
// In this test if --cfg foo is passed the build will fail.
let p = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
build = "build.rs"
"#)
.file("src/lib.rs", "")
.file("build.rs", r#"
fn main() { }
#[cfg(not(foo))]
fn main() { }
"#);
p.build();

assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
execs().with_status(0));
});

test!(rustflags_build_script_dep {
// RUSTFLAGS should be passed to rustc for build scripts
// when --target is not specified.
// In this test if --cfg foo is not passed the build will fail.
let foo = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
build = "build.rs"
[build-dependencies.bar]
path = "../bar"
"#)
.file("src/lib.rs", "")
.file("build.rs", r#"
fn main() { }
"#);
let bar = project("bar")
.file("Cargo.toml", r#"
[package]
name = "bar"
version = "0.0.1"
"#)
.file("src/lib.rs", r#"
fn bar() { }
#[cfg(not(foo))]
fn bar() { }
"#);
foo.build();
bar.build();

assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo"),
execs().with_status(0));
});

test!(rustflags_plugin {
// RUSTFLAGS should be passed to rustc for plugins
// when --target is not specified.
// In this test if --cfg foo is not passed the build will fail.
let p = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
[lib]
name = "foo"
plugin = true
"#)
.file("src/lib.rs", r#"
fn main() { }
#[cfg(not(foo))]
fn main() { }
"#);
p.build();

assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
execs().with_status(0));
});

test!(rustflags_plugin_dep {
// RUSTFLAGS should be passed to rustc for plugins
// when --target is not specified.
// In this test if --cfg foo is not passed the build will fail.
let foo = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
[lib]
name = "foo"
plugin = true
[dependencies.bar]
path = "../bar"
"#)
.file("src/lib.rs", r#"
fn foo() { }
"#);
let bar = project("bar")
.file("Cargo.toml", r#"
[package]
name = "bar"
version = "0.0.1"
[lib]
name = "bar"
"#)
.file("src/lib.rs", r#"
fn bar() { }
#[cfg(not(foo))]
fn bar() { }
"#);
foo.build();
bar.build();

assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo"),
execs().with_status(0));
});

test!(rustflags_normal_source_with_target {
let p = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
"#)
.file("src/lib.rs", "")
.file("src/bin/a.rs", "fn main() {}")
.file("examples/b.rs", "fn main() {}")
.file("tests/c.rs", "#[test] fn f() { }")
.file("benches/d.rs", r#"
#![feature(test)]
extern crate test;
#[bench] fn run1(_ben: &mut test::Bencher) { }"#);
p.build();

let ref host = ::rustc_host();

// Use RUSTFLAGS to pass an argument that will generate an error
assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
.arg("--lib").arg("--target").arg(host),
execs().with_status(101));
assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
.arg("--bin=a").arg("--target").arg(host),
execs().with_status(101));
assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
.arg("--bin=b").arg("--target").arg(host),
execs().with_status(101));
assert_that(p.cargo("check").env("RUSTFLAGS", "-Z bogus")
.arg("--target").arg(host),
execs().with_status(101));
assert_that(p.cargo("bench").env("RUSTFLAGS", "-Z bogus")
.arg("--target").arg(host),
execs().with_status(101));
});

test!(rustflags_build_script_with_target {
// RUSTFLAGS should not be passed to rustc for build scripts
// when --target is specified.
// In this test if --cfg foo is passed the build will fail.
let p = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
build = "build.rs"
"#)
.file("src/lib.rs", "")
.file("build.rs", r#"
fn main() { }
#[cfg(foo)]
fn main() { }
"#);
p.build();

let host = ::rustc_host();
assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo")
.arg("--target").arg(host),
execs().with_status(0));
});

test!(rustflags_build_script_dep_with_target {
// RUSTFLAGS should not be passed to rustc for build scripts
// when --target is specified.
// In this test if --cfg foo is passed the build will fail.
let foo = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
build = "build.rs"
[build-dependencies.bar]
path = "../bar"
"#)
.file("src/lib.rs", "")
.file("build.rs", r#"
fn main() { }
"#);
let bar = project("bar")
.file("Cargo.toml", r#"
[package]
name = "bar"
version = "0.0.1"
"#)
.file("src/lib.rs", r#"
fn bar() { }
#[cfg(foo)]
fn bar() { }
"#);
foo.build();
bar.build();

let host = ::rustc_host();
assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo")
.arg("--target").arg(host),
execs().with_status(0));
});

test!(rustflags_plugin_with_target {
// RUSTFLAGS should not be passed to rustc for plugins
// when --target is specified.
// In this test if --cfg foo is passed the build will fail.
let p = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
[lib]
name = "foo"
plugin = true
"#)
.file("src/lib.rs", r#"
fn main() { }
#[cfg(foo)]
fn main() { }
"#);
p.build();

let host = ::rustc_host();
assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo")
.arg("--target").arg(host),
execs().with_status(0));
});

test!(rustflags_plugin_dep_with_target {
// RUSTFLAGS should not be passed to rustc for plugins
// when --target is specified.
// In this test if --cfg foo is passed the build will fail.
let foo = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
[lib]
name = "foo"
plugin = true
[dependencies.bar]
path = "../bar"
"#)
.file("src/lib.rs", r#"
fn foo() { }
"#);
let bar = project("bar")
.file("Cargo.toml", r#"
[package]
name = "bar"
version = "0.0.1"
[lib]
name = "bar"
"#)
.file("src/lib.rs", r#"
fn bar() { }
#[cfg(foo)]
fn bar() { }
"#);
foo.build();
bar.build();

let host = ::rustc_host();
assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo")
.arg("--target").arg(host),
execs().with_status(0));
});

test!(rustflags_recompile {
let p = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
"#)
.file("src/lib.rs", "");
p.build();

assert_that(p.cargo("build"),
execs().with_status(0));
// Setting RUSTFLAGS forces a recompile
assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus"),
execs().with_status(101));
});

test!(rustflags_recompile2 {
let p = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
"#)
.file("src/lib.rs", "");
p.build();

assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
execs().with_status(0));
// Setting RUSTFLAGS forces a recompile
assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus"),
execs().with_status(101));
});

test!(rustflags_no_recompile {
let p = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
"#)
.file("src/lib.rs", "");
p.build();

assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
execs().with_status(0));
assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
execs().with_stdout("").with_status(0));
});

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -45,6 +45,7 @@ mod test_cargo_compile_custom_build;
mod test_cargo_compile_git_deps;
mod test_cargo_compile_path_deps;
mod test_cargo_compile_plugins;
mod test_cargo_compile_rustflags;
mod test_cargo_cross_compile;
mod test_cargo_doc;
mod test_cargo_features;