From 75848a2a6972a3de95dd8d0a52ff2cf0443adad7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 13 May 2016 11:35:52 -0700 Subject: [PATCH] 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]: https://github.com/rust-lang/rfcs/pull/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. --- src/cargo/core/manifest.rs | 4 ++++ src/cargo/ops/cargo_clean.rs | 6 +++-- src/cargo/ops/cargo_compile.rs | 1 + src/cargo/ops/cargo_rustc/context.rs | 11 +++++++--- src/cargo/ops/cargo_rustc/mod.rs | 7 +++++- src/cargo/util/toml.rs | 14 ++++++++++-- src/rustversion.txt | 2 +- tests/test_cargo_compile.rs | 20 +++++++++++++++++ tests/test_cargo_test.rs | 33 ++++++++++++++++++++++++++++ 9 files changed, 89 insertions(+), 9 deletions(-) diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index a988460f676..00639978c48 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -113,6 +113,7 @@ pub struct Profile { pub test: bool, pub doc: bool, pub run_custom_build: bool, + pub panic: Option, } #[derive(Default, Clone, Debug)] @@ -120,7 +121,9 @@ 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, } @@ -469,6 +472,7 @@ impl Default for Profile { test: false, doc: false, run_custom_build: false, + panic: None, } } } diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs index f5dfdb0d900..6056071712c 100644 --- a/src/cargo/ops/cargo_clean.rs +++ b/src/cargo/ops/cargo_clean.rs @@ -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, diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index d330ea3ce29..9ae3f007c6c 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -244,6 +244,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; } diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index 62f9e9818d9..0c914b40693 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -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 } } diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index ab1ce343e33..c7c6e625250 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -40,6 +40,7 @@ pub struct BuildConfig { pub requested_target: Option, pub exec_engine: Option>>, pub release: bool, + pub test: bool, pub doc_all: bool, } @@ -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); @@ -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() { diff --git a/src/cargo/util/toml.rs b/src/cargo/util/toml.rs index 5e0d3868e39..82ea4533aca 100644 --- a/src/cargo/util/toml.rs +++ b/src/cargo/util/toml.rs @@ -238,6 +238,7 @@ pub struct TomlProfile { debug: Option, debug_assertions: Option, rpath: Option, + panic: Option, } #[derive(RustcDecodable)] @@ -1030,23 +1031,31 @@ fn normalize(lib: &Option, fn build_profiles(profiles: &Option) -> 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, @@ -1063,6 +1072,7 @@ fn build_profiles(profiles: &Option) -> Profiles { test: profile.test, doc: profile.doc, run_custom_build: profile.run_custom_build, + panic: panic.clone().or(profile.panic), } } } diff --git a/src/rustversion.txt b/src/rustversion.txt index f3e7aced58b..1557cfb2fe4 100644 --- a/src/rustversion.txt +++ b/src/rustversion.txt @@ -1 +1 @@ -2016-04-23 +2016-05-13 diff --git a/tests/test_cargo_compile.rs b/tests/test_cargo_compile.rs index 58246eb04f4..46772789ae3 100644 --- a/tests/test_cargo_compile.rs +++ b/tests/test_cargo_compile.rs @@ -2128,3 +2128,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 [..]")); +}); diff --git a/tests/test_cargo_test.rs b/tests/test_cargo_test.rs index 7d0493e3ba7..1145f91f3dc 100644 --- a/tests/test_cargo_test.rs +++ b/tests/test_cargo_test.rs @@ -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)); +});