Skip to content

Commit 75848a2

Browse files
committed
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.
1 parent 235e2c2 commit 75848a2

9 files changed

+89
-9
lines changed

src/cargo/core/manifest.rs

+4
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,17 @@ pub struct Profile {
113113
pub test: bool,
114114
pub doc: bool,
115115
pub run_custom_build: bool,
116+
pub panic: Option<String>,
116117
}
117118

118119
#[derive(Default, Clone, Debug)]
119120
pub struct Profiles {
120121
pub release: Profile,
121122
pub dev: Profile,
122123
pub test: Profile,
124+
pub test_deps: Profile,
123125
pub bench: Profile,
126+
pub bench_deps: Profile,
124127
pub doc: Profile,
125128
pub custom_build: Profile,
126129
}
@@ -469,6 +472,7 @@ impl Default for Profile {
469472
test: false,
470473
doc: false,
471474
run_custom_build: false,
475+
panic: None,
472476
}
473477
}
474478
}

src/cargo/ops/cargo_clean.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,11 @@ pub fn clean(manifest_path: &Path, opts: &CleanOptions) -> CargoResult<()> {
5858
try!(rm_rf(&layout.build(&pkg)));
5959
let Profiles {
6060
ref release, ref dev, ref test, ref bench, ref doc,
61-
ref custom_build,
61+
ref custom_build, ref test_deps, ref bench_deps,
6262
} = *root.manifest().profiles();
63-
for profile in [release, dev, test, bench, doc, custom_build].iter() {
63+
let profiles = [release, dev, test, bench, doc, custom_build,
64+
test_deps, bench_deps];
65+
for profile in profiles.iter() {
6466
let unit = Unit {
6567
pkg: &pkg,
6668
target: target,

src/cargo/ops/cargo_compile.rs

+1
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ pub fn compile_pkg<'a>(root_package: &Package,
244244
let mut build_config = try!(scrape_build_config(config, jobs, target));
245245
build_config.exec_engine = exec_engine.clone();
246246
build_config.release = release;
247+
build_config.test = mode == CompileMode::Test;
247248
if let CompileMode::Doc { deps } = mode {
248249
build_config.doc_all = deps;
249250
}

src/cargo/ops/cargo_rustc/context.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -620,10 +620,15 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
620620
}
621621

622622
pub fn lib_profile(&self, _pkg: &PackageId) -> &'a Profile {
623-
if self.build_config.release {
624-
&self.profiles.release
623+
let (normal, test) = if self.build_config.release {
624+
(&self.profiles.release, &self.profiles.bench_deps)
625625
} else {
626-
&self.profiles.dev
626+
(&self.profiles.dev, &self.profiles.test_deps)
627+
};
628+
if self.build_config.test {
629+
test
630+
} else {
631+
normal
627632
}
628633
}
629634

src/cargo/ops/cargo_rustc/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub struct BuildConfig {
4040
pub requested_target: Option<String>,
4141
pub exec_engine: Option<Arc<Box<ExecEngine>>>,
4242
pub release: bool,
43+
pub test: bool,
4344
pub doc_all: bool,
4445
}
4546

@@ -451,7 +452,7 @@ fn build_base_args(cx: &Context,
451452
let Profile {
452453
opt_level, lto, codegen_units, ref rustc_args, debuginfo,
453454
debug_assertions, rpath, test, doc: _doc, run_custom_build,
454-
rustdoc_args: _,
455+
ref panic, rustdoc_args: _,
455456
} = *unit.profile;
456457
assert!(!run_custom_build);
457458

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

482+
if let Some(panic) = panic.as_ref() {
483+
cmd.arg("-C").arg(format!("panic={}", panic));
484+
}
485+
481486
// Disable LTO for host builds as prefer_dynamic and it are mutually
482487
// exclusive.
483488
if unit.target.can_lto() && lto && !unit.target.for_host() {

src/cargo/util/toml.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ pub struct TomlProfile {
238238
debug: Option<bool>,
239239
debug_assertions: Option<bool>,
240240
rpath: Option<bool>,
241+
panic: Option<String>,
241242
}
242243

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

10311032
fn build_profiles(profiles: &Option<TomlProfiles>) -> Profiles {
10321033
let profiles = profiles.as_ref();
1033-
return Profiles {
1034+
let mut profiles = Profiles {
10341035
release: merge(Profile::default_release(),
10351036
profiles.and_then(|p| p.release.as_ref())),
10361037
dev: merge(Profile::default_dev(),
10371038
profiles.and_then(|p| p.dev.as_ref())),
10381039
test: merge(Profile::default_test(),
10391040
profiles.and_then(|p| p.test.as_ref())),
1041+
test_deps: merge(Profile::default_dev(),
1042+
profiles.and_then(|p| p.dev.as_ref())),
10401043
bench: merge(Profile::default_bench(),
10411044
profiles.and_then(|p| p.bench.as_ref())),
1045+
bench_deps: merge(Profile::default_release(),
1046+
profiles.and_then(|p| p.release.as_ref())),
10421047
doc: merge(Profile::default_doc(),
10431048
profiles.and_then(|p| p.doc.as_ref())),
10441049
custom_build: Profile::default_custom_build(),
10451050
};
1051+
profiles.test_deps.panic = None;
1052+
profiles.bench_deps.panic = None;
1053+
return profiles;
10461054

10471055
fn merge(profile: Profile, toml: Option<&TomlProfile>) -> Profile {
10481056
let &TomlProfile {
1049-
opt_level, lto, codegen_units, debug, debug_assertions, rpath
1057+
opt_level, lto, codegen_units, debug, debug_assertions, rpath,
1058+
ref panic
10501059
} = match toml {
10511060
Some(toml) => toml,
10521061
None => return profile,
@@ -1063,6 +1072,7 @@ fn build_profiles(profiles: &Option<TomlProfiles>) -> Profiles {
10631072
test: profile.test,
10641073
doc: profile.doc,
10651074
run_custom_build: profile.run_custom_build,
1075+
panic: panic.clone().or(profile.panic),
10661076
}
10671077
}
10681078
}

src/rustversion.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2016-04-23
1+
2016-05-13

tests/test_cargo_compile.rs

+20
Original file line numberDiff line numberDiff line change
@@ -2128,3 +2128,23 @@ test!(manifest_with_bom_is_ok {
21282128
assert_that(p.cargo_process("build").arg("-v"),
21292129
execs().with_status(0));
21302130
});
2131+
2132+
test!(panic_abort_compiles_with_panic_abort {
2133+
if !::is_nightly() {
2134+
return
2135+
}
2136+
let p = project("foo")
2137+
.file("Cargo.toml", r#"
2138+
[package]
2139+
name = "foo"
2140+
version = "0.0.1"
2141+
authors = []
2142+
2143+
[profile.dev]
2144+
panic = 'abort'
2145+
"#)
2146+
.file("src/lib.rs", "");
2147+
assert_that(p.cargo_process("build").arg("-v"),
2148+
execs().with_status(0)
2149+
.with_stderr_contains("[..] -C panic=abort [..]"));
2150+
});

tests/test_cargo_test.rs

+33
Original file line numberDiff line numberDiff line change
@@ -2072,3 +2072,36 @@ test result: ok.[..]
20722072
"));
20732073
});
20742074

2075+
test!(test_panic_abort_with_dep {
2076+
if !::is_nightly() {
2077+
return
2078+
}
2079+
let p = project("foo")
2080+
.file("Cargo.toml", r#"
2081+
[package]
2082+
name = "foo"
2083+
version = "0.0.1"
2084+
authors = []
2085+
2086+
[dependencies]
2087+
bar = { path = "bar" }
2088+
2089+
[profile.dev]
2090+
panic = 'abort'
2091+
"#)
2092+
.file("src/lib.rs", r#"
2093+
extern crate bar;
2094+
2095+
#[test]
2096+
fn foo() {}
2097+
"#)
2098+
.file("bar/Cargo.toml", r#"
2099+
[package]
2100+
name = "bar"
2101+
version = "0.0.1"
2102+
authors = []
2103+
"#)
2104+
.file("bar/src/lib.rs", "");
2105+
assert_that(p.cargo_process("test").arg("-v"),
2106+
execs().with_status(0));
2107+
});

0 commit comments

Comments
 (0)