Skip to content

Commit

Permalink
Auto merge of #2687 - alexcrichton:panic-abort, r=wycats
Browse files Browse the repository at this point in the history
Implement the `panic` profile option

This is the Cargo half of the implementation of [RFC 1513] which adds a new
`profile.*.panic` option to customize the `-C panic` argument to the compiler.
This is not passed by default and can otherwise be specified as `abort` or
`unwind` on the nightly compiler.

[RFC 1513]: rust-lang/rfcs#1513

The `profile.*.panic` option is *only* used from the top-level crate, not each
crate individually. This means that applications should customize this value as
they see fit, and libraries will only use their own value when they're being
tested.

Cargo also has specific knowledge that when *testing* a crate it can't pass
`-C panic=abort` for now as the default test harness requires `panic=unwind`.
This essentially just means that `cargo test` will continue to work for crates
that specify `panic=abort` in Cargo.toml.
  • Loading branch information
bors committed May 21, 2016
2 parents f13ca72 + 75848a2 commit 259324c
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 9 deletions.
4 changes: 4 additions & 0 deletions src/cargo/core/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,17 @@ pub struct Profile {
pub test: bool,
pub doc: bool,
pub run_custom_build: bool,
pub panic: Option<String>,
}

#[derive(Default, Clone, Debug)]
pub struct Profiles {
pub release: Profile,
pub dev: Profile,
pub test: Profile,
pub test_deps: Profile,
pub bench: Profile,
pub bench_deps: Profile,
pub doc: Profile,
pub custom_build: Profile,
}
Expand Down Expand Up @@ -469,6 +472,7 @@ impl Default for Profile {
test: false,
doc: false,
run_custom_build: false,
panic: None,
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/cargo/ops/cargo_clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ pub fn clean(manifest_path: &Path, opts: &CleanOptions) -> CargoResult<()> {
try!(rm_rf(&layout.build(&pkg)));
let Profiles {
ref release, ref dev, ref test, ref bench, ref doc,
ref custom_build,
ref custom_build, ref test_deps, ref bench_deps,
} = *root.manifest().profiles();
for profile in [release, dev, test, bench, doc, custom_build].iter() {
let profiles = [release, dev, test, bench, doc, custom_build,
test_deps, bench_deps];
for profile in profiles.iter() {
let unit = Unit {
pkg: &pkg,
target: target,
Expand Down
1 change: 1 addition & 0 deletions src/cargo/ops/cargo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ pub fn compile_pkg<'a>(root_package: &Package,
let mut build_config = try!(scrape_build_config(config, jobs, target));
build_config.exec_engine = exec_engine.clone();
build_config.release = release;
build_config.test = mode == CompileMode::Test;
if let CompileMode::Doc { deps } = mode {
build_config.doc_all = deps;
}
Expand Down
11 changes: 8 additions & 3 deletions src/cargo/ops/cargo_rustc/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,10 +620,15 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
}

pub fn lib_profile(&self, _pkg: &PackageId) -> &'a Profile {
if self.build_config.release {
&self.profiles.release
let (normal, test) = if self.build_config.release {
(&self.profiles.release, &self.profiles.bench_deps)
} else {
&self.profiles.dev
(&self.profiles.dev, &self.profiles.test_deps)
};
if self.build_config.test {
test
} else {
normal
}
}

Expand Down
7 changes: 6 additions & 1 deletion src/cargo/ops/cargo_rustc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub struct BuildConfig {
pub requested_target: Option<String>,
pub exec_engine: Option<Arc<Box<ExecEngine>>>,
pub release: bool,
pub test: bool,
pub doc_all: bool,
}

Expand Down Expand Up @@ -451,7 +452,7 @@ fn build_base_args(cx: &Context,
let Profile {
opt_level, lto, codegen_units, ref rustc_args, debuginfo,
debug_assertions, rpath, test, doc: _doc, run_custom_build,
rustdoc_args: _,
ref panic, rustdoc_args: _,
} = *unit.profile;
assert!(!run_custom_build);

Expand All @@ -478,6 +479,10 @@ fn build_base_args(cx: &Context,
cmd.arg("-C").arg(&format!("opt-level={}", opt_level));
}

if let Some(panic) = panic.as_ref() {
cmd.arg("-C").arg(format!("panic={}", panic));
}

// Disable LTO for host builds as prefer_dynamic and it are mutually
// exclusive.
if unit.target.can_lto() && lto && !unit.target.for_host() {
Expand Down
14 changes: 12 additions & 2 deletions src/cargo/util/toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ pub struct TomlProfile {
debug: Option<bool>,
debug_assertions: Option<bool>,
rpath: Option<bool>,
panic: Option<String>,
}

#[derive(RustcDecodable)]
Expand Down Expand Up @@ -1030,23 +1031,31 @@ fn normalize(lib: &Option<TomlLibTarget>,

fn build_profiles(profiles: &Option<TomlProfiles>) -> Profiles {
let profiles = profiles.as_ref();
return Profiles {
let mut profiles = Profiles {
release: merge(Profile::default_release(),
profiles.and_then(|p| p.release.as_ref())),
dev: merge(Profile::default_dev(),
profiles.and_then(|p| p.dev.as_ref())),
test: merge(Profile::default_test(),
profiles.and_then(|p| p.test.as_ref())),
test_deps: merge(Profile::default_dev(),
profiles.and_then(|p| p.dev.as_ref())),
bench: merge(Profile::default_bench(),
profiles.and_then(|p| p.bench.as_ref())),
bench_deps: merge(Profile::default_release(),
profiles.and_then(|p| p.release.as_ref())),
doc: merge(Profile::default_doc(),
profiles.and_then(|p| p.doc.as_ref())),
custom_build: Profile::default_custom_build(),
};
profiles.test_deps.panic = None;
profiles.bench_deps.panic = None;
return profiles;

fn merge(profile: Profile, toml: Option<&TomlProfile>) -> Profile {
let &TomlProfile {
opt_level, lto, codegen_units, debug, debug_assertions, rpath
opt_level, lto, codegen_units, debug, debug_assertions, rpath,
ref panic
} = match toml {
Some(toml) => toml,
None => return profile,
Expand All @@ -1063,6 +1072,7 @@ fn build_profiles(profiles: &Option<TomlProfiles>) -> Profiles {
test: profile.test,
doc: profile.doc,
run_custom_build: profile.run_custom_build,
panic: panic.clone().or(profile.panic),
}
}
}
2 changes: 1 addition & 1 deletion src/rustversion.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2016-04-23
2016-05-13
20 changes: 20 additions & 0 deletions tests/test_cargo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2129,3 +2129,23 @@ test!(manifest_with_bom_is_ok {
assert_that(p.cargo_process("build").arg("-v"),
execs().with_status(0));
});

test!(panic_abort_compiles_with_panic_abort {
if !::is_nightly() {
return
}
let p = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
[profile.dev]
panic = 'abort'
"#)
.file("src/lib.rs", "");
assert_that(p.cargo_process("build").arg("-v"),
execs().with_status(0)
.with_stderr_contains("[..] -C panic=abort [..]"));
});
33 changes: 33 additions & 0 deletions tests/test_cargo_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2072,3 +2072,36 @@ test result: ok.[..]
"));
});

test!(test_panic_abort_with_dep {
if !::is_nightly() {
return
}
let p = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
[dependencies]
bar = { path = "bar" }
[profile.dev]
panic = 'abort'
"#)
.file("src/lib.rs", r#"
extern crate bar;
#[test]
fn foo() {}
"#)
.file("bar/Cargo.toml", r#"
[package]
name = "bar"
version = "0.0.1"
authors = []
"#)
.file("bar/src/lib.rs", "");
assert_that(p.cargo_process("test").arg("-v"),
execs().with_status(0));
});

0 comments on commit 259324c

Please sign in to comment.