mirror of
https://github.com/rust-lang/cargo
synced 2024-10-14 03:32:39 +00:00
d861dcf792
Rustc supports these since rust-lang/rust#109808. It's technically possible to set a named debuginfo level through `RUSTFLAGS`, but in practice cargo always passes its own opinion of what the debuginfo level is, so allow it to be configured through cargo too.
521 lines
14 KiB
Rust
521 lines
14 KiB
Rust
//! Tests for profiles defined in config files.
|
|
|
|
use cargo::util::toml::TomlDebugInfo;
|
|
use cargo_test_support::paths::CargoPathExt;
|
|
use cargo_test_support::registry::Package;
|
|
use cargo_test_support::{basic_lib_manifest, paths, project};
|
|
|
|
// TODO: this should be remove once -Zprofile-rustflags is stabilized
|
|
#[cargo_test]
|
|
fn rustflags_works_with_zflag() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
"#,
|
|
)
|
|
.file("src/main.rs", "fn main() {}")
|
|
.file(
|
|
".cargo/config.toml",
|
|
r#"
|
|
[profile.dev]
|
|
rustflags = ["-C", "link-dead-code=yes"]
|
|
"#,
|
|
)
|
|
.build();
|
|
|
|
p.cargo("check -v")
|
|
.masquerade_as_nightly_cargo(&["profile-rustflags"])
|
|
.with_status(101)
|
|
.with_stderr_contains("[..]feature `profile-rustflags` is required[..]")
|
|
.run();
|
|
|
|
p.cargo("check -v -Zprofile-rustflags")
|
|
.masquerade_as_nightly_cargo(&["profile-rustflags"])
|
|
.with_stderr(
|
|
"\
|
|
[CHECKING] foo [..]
|
|
[RUNNING] `rustc --crate-name foo [..] -C link-dead-code=yes [..]
|
|
[FINISHED] [..]
|
|
",
|
|
)
|
|
.run();
|
|
|
|
p.change_file(
|
|
".cargo/config.toml",
|
|
r#"
|
|
[unstable]
|
|
profile-rustflags = true
|
|
|
|
[profile.dev]
|
|
rustflags = ["-C", "link-dead-code=yes"]
|
|
"#,
|
|
);
|
|
|
|
p.cargo("check -v")
|
|
.masquerade_as_nightly_cargo(&["profile-rustflags"])
|
|
.with_stderr(
|
|
"\
|
|
[FRESH] foo [..]
|
|
[FINISHED] [..]
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn profile_config_validate_warnings() {
|
|
let p = project()
|
|
.file("Cargo.toml", &basic_lib_manifest("foo"))
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
".cargo/config",
|
|
r#"
|
|
[profile.test]
|
|
opt-level = 3
|
|
|
|
[profile.asdf]
|
|
opt-level = 3
|
|
|
|
[profile.dev]
|
|
bad-key = true
|
|
|
|
[profile.dev.build-override]
|
|
bad-key-bo = true
|
|
|
|
[profile.dev.package.bar]
|
|
bad-key-bar = true
|
|
"#,
|
|
)
|
|
.build();
|
|
|
|
p.cargo("build")
|
|
.with_stderr_unordered(
|
|
"\
|
|
[WARNING] unused config key `profile.dev.bad-key` in `[..].cargo/config`
|
|
[WARNING] unused config key `profile.dev.package.bar.bad-key-bar` in `[..].cargo/config`
|
|
[WARNING] unused config key `profile.dev.build-override.bad-key-bo` in `[..].cargo/config`
|
|
[COMPILING] foo [..]
|
|
[FINISHED] [..]
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn profile_config_error_paths() {
|
|
// Errors in config show where the error is located.
|
|
let p = project()
|
|
.file("Cargo.toml", &basic_lib_manifest("foo"))
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
".cargo/config",
|
|
r#"
|
|
[profile.dev]
|
|
opt-level = 3
|
|
"#,
|
|
)
|
|
.file(
|
|
paths::home().join(".cargo/config"),
|
|
r#"
|
|
[profile.dev]
|
|
rpath = "foo"
|
|
"#,
|
|
)
|
|
.build();
|
|
|
|
p.cargo("build")
|
|
.with_status(101)
|
|
.with_stderr(
|
|
"\
|
|
[ERROR] error in [..]/foo/.cargo/config: could not load config key `profile.dev`
|
|
|
|
Caused by:
|
|
error in [..]/home/.cargo/config: `profile.dev.rpath` expected true/false, but found a string
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn profile_config_validate_errors() {
|
|
let p = project()
|
|
.file("Cargo.toml", &basic_lib_manifest("foo"))
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
".cargo/config",
|
|
r#"
|
|
[profile.dev.package.foo]
|
|
panic = "abort"
|
|
"#,
|
|
)
|
|
.build();
|
|
|
|
p.cargo("build")
|
|
.with_status(101)
|
|
.with_stderr(
|
|
"\
|
|
[ERROR] config profile `dev` is not valid (defined in `[..]/foo/.cargo/config`)
|
|
|
|
Caused by:
|
|
`panic` may not be specified in a `package` profile
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn profile_config_syntax_errors() {
|
|
let p = project()
|
|
.file("Cargo.toml", &basic_lib_manifest("foo"))
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
".cargo/config",
|
|
r#"
|
|
[profile.dev]
|
|
codegen-units = "foo"
|
|
"#,
|
|
)
|
|
.build();
|
|
|
|
p.cargo("build")
|
|
.with_status(101)
|
|
.with_stderr(
|
|
"\
|
|
[ERROR] error in [..]/.cargo/config: could not load config key `profile.dev`
|
|
|
|
Caused by:
|
|
error in [..]/foo/.cargo/config: `profile.dev.codegen-units` expected an integer, but found a string
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn profile_config_override_spec_multiple() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
|
|
[dependencies]
|
|
bar = { path = "bar" }
|
|
"#,
|
|
)
|
|
.file(
|
|
".cargo/config",
|
|
r#"
|
|
[profile.dev.package.bar]
|
|
opt-level = 3
|
|
|
|
[profile.dev.package."bar:0.5.0"]
|
|
opt-level = 3
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("bar/Cargo.toml", &basic_lib_manifest("bar"))
|
|
.file("bar/src/lib.rs", "")
|
|
.build();
|
|
|
|
// Unfortunately this doesn't tell you which file, hopefully it's not too
|
|
// much of a problem.
|
|
p.cargo("build -v")
|
|
.with_status(101)
|
|
.with_stderr(
|
|
"\
|
|
[ERROR] multiple package overrides in profile `dev` match package `bar v0.5.0 ([..])`
|
|
found package specs: bar, bar@0.5.0",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn profile_config_all_options() {
|
|
// Ensure all profile options are supported.
|
|
let p = project()
|
|
.file("src/main.rs", "fn main() {}")
|
|
.file(
|
|
".cargo/config",
|
|
r#"
|
|
[profile.release]
|
|
opt-level = 1
|
|
debug = true
|
|
debug-assertions = true
|
|
overflow-checks = false
|
|
rpath = true
|
|
lto = true
|
|
codegen-units = 2
|
|
panic = "abort"
|
|
incremental = true
|
|
"#,
|
|
)
|
|
.build();
|
|
|
|
p.cargo("build --release -v")
|
|
.env_remove("CARGO_INCREMENTAL")
|
|
.with_stderr(
|
|
"\
|
|
[COMPILING] foo [..]
|
|
[RUNNING] `rustc --crate-name foo [..] \
|
|
-C opt-level=1 \
|
|
-C panic=abort \
|
|
-C lto[..]\
|
|
-C codegen-units=2 \
|
|
-C debuginfo=2 \
|
|
-C debug-assertions=on \
|
|
-C overflow-checks=off [..]\
|
|
-C rpath [..]\
|
|
-C incremental=[..]
|
|
[FINISHED] release [optimized + debuginfo] [..]
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn profile_config_override_precedence() {
|
|
// Config values take precedence over manifest values.
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
|
|
[dependencies]
|
|
bar = {path = "bar"}
|
|
|
|
[profile.dev]
|
|
codegen-units = 2
|
|
|
|
[profile.dev.package.bar]
|
|
opt-level = 3
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("bar/Cargo.toml", &basic_lib_manifest("bar"))
|
|
.file("bar/src/lib.rs", "")
|
|
.file(
|
|
".cargo/config",
|
|
r#"
|
|
[profile.dev.package.bar]
|
|
opt-level = 2
|
|
"#,
|
|
)
|
|
.build();
|
|
|
|
p.cargo("build -v")
|
|
.with_stderr(
|
|
"\
|
|
[COMPILING] bar [..]
|
|
[RUNNING] `rustc --crate-name bar [..] -C opt-level=2[..]-C codegen-units=2 [..]
|
|
[COMPILING] foo [..]
|
|
[RUNNING] `rustc --crate-name foo [..]-C codegen-units=2 [..]
|
|
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn profile_config_no_warn_unknown_override() {
|
|
let p = project()
|
|
.file("Cargo.toml", &basic_lib_manifest("foo"))
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
".cargo/config",
|
|
r#"
|
|
[profile.dev.package.bar]
|
|
codegen-units = 4
|
|
"#,
|
|
)
|
|
.build();
|
|
|
|
p.cargo("build")
|
|
.with_stderr_does_not_contain("[..]warning[..]")
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn profile_config_mixed_types() {
|
|
let p = project()
|
|
.file("Cargo.toml", &basic_lib_manifest("foo"))
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
".cargo/config",
|
|
r#"
|
|
[profile.dev]
|
|
opt-level = 3
|
|
"#,
|
|
)
|
|
.file(
|
|
paths::home().join(".cargo/config"),
|
|
r#"
|
|
[profile.dev]
|
|
opt-level = 's'
|
|
"#,
|
|
)
|
|
.build();
|
|
|
|
p.cargo("build -v")
|
|
.with_stderr_contains("[..]-C opt-level=3 [..]")
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn named_config_profile() {
|
|
// Exercises config named profies.
|
|
// foo -> middle -> bar -> dev
|
|
// middle exists in Cargo.toml, the others in .cargo/config
|
|
use super::config::ConfigBuilder;
|
|
use cargo::core::compiler::CompileKind;
|
|
use cargo::core::profiles::{Profiles, UnitFor};
|
|
use cargo::core::{PackageId, Workspace};
|
|
use cargo::util::interning::InternedString;
|
|
use std::fs;
|
|
paths::root().join(".cargo").mkdir_p();
|
|
fs::write(
|
|
paths::root().join(".cargo/config"),
|
|
r#"
|
|
[profile.foo]
|
|
inherits = "middle"
|
|
codegen-units = 2
|
|
[profile.foo.build-override]
|
|
codegen-units = 6
|
|
[profile.foo.package.dep]
|
|
codegen-units = 7
|
|
|
|
[profile.middle]
|
|
inherits = "bar"
|
|
codegen-units = 3
|
|
|
|
[profile.bar]
|
|
inherits = "dev"
|
|
codegen-units = 4
|
|
debug = 1
|
|
"#,
|
|
)
|
|
.unwrap();
|
|
fs::write(
|
|
paths::root().join("Cargo.toml"),
|
|
r#"
|
|
[workspace]
|
|
|
|
[profile.middle]
|
|
inherits = "bar"
|
|
codegen-units = 1
|
|
opt-level = 1
|
|
[profile.middle.package.dep]
|
|
overflow-checks = false
|
|
|
|
[profile.foo.build-override]
|
|
codegen-units = 5
|
|
debug-assertions = false
|
|
[profile.foo.package.dep]
|
|
codegen-units = 8
|
|
"#,
|
|
)
|
|
.unwrap();
|
|
let config = ConfigBuilder::new().build();
|
|
let profile_name = InternedString::new("foo");
|
|
let ws = Workspace::new(&paths::root().join("Cargo.toml"), &config).unwrap();
|
|
let profiles = Profiles::new(&ws, profile_name).unwrap();
|
|
|
|
let crates_io = cargo::core::source::SourceId::crates_io(&config).unwrap();
|
|
let a_pkg = PackageId::new("a", "0.1.0", crates_io).unwrap();
|
|
let dep_pkg = PackageId::new("dep", "0.1.0", crates_io).unwrap();
|
|
|
|
// normal package
|
|
let kind = CompileKind::Host;
|
|
let p = profiles.get_profile(a_pkg, true, true, UnitFor::new_normal(kind), kind);
|
|
assert_eq!(p.name, "foo");
|
|
assert_eq!(p.codegen_units, Some(2)); // "foo" from config
|
|
assert_eq!(p.opt_level, "1"); // "middle" from manifest
|
|
assert_eq!(p.debuginfo.to_option(), Some(TomlDebugInfo::Limited)); // "bar" from config
|
|
assert_eq!(p.debug_assertions, true); // "dev" built-in (ignore build-override)
|
|
assert_eq!(p.overflow_checks, true); // "dev" built-in (ignore package override)
|
|
|
|
// build-override
|
|
let bo = profiles.get_profile(a_pkg, true, true, UnitFor::new_host(false, kind), kind);
|
|
assert_eq!(bo.name, "foo");
|
|
assert_eq!(bo.codegen_units, Some(6)); // "foo" build override from config
|
|
assert_eq!(bo.opt_level, "0"); // default to zero
|
|
assert_eq!(bo.debuginfo.to_option(), Some(TomlDebugInfo::Limited)); // SAME as normal
|
|
assert_eq!(bo.debug_assertions, false); // "foo" build override from manifest
|
|
assert_eq!(bo.overflow_checks, true); // SAME as normal
|
|
|
|
// package overrides
|
|
let po = profiles.get_profile(dep_pkg, false, true, UnitFor::new_normal(kind), kind);
|
|
assert_eq!(po.name, "foo");
|
|
assert_eq!(po.codegen_units, Some(7)); // "foo" package override from config
|
|
assert_eq!(po.opt_level, "1"); // SAME as normal
|
|
assert_eq!(po.debuginfo.to_option(), Some(TomlDebugInfo::Limited)); // SAME as normal
|
|
assert_eq!(po.debug_assertions, true); // SAME as normal
|
|
assert_eq!(po.overflow_checks, false); // "middle" package override from manifest
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn named_env_profile() {
|
|
// Environment variables used to define a named profile.
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.build();
|
|
|
|
p.cargo("build -v --profile=other")
|
|
.env("CARGO_PROFILE_OTHER_CODEGEN_UNITS", "1")
|
|
.env("CARGO_PROFILE_OTHER_INHERITS", "dev")
|
|
.with_stderr_contains("[..]-C codegen-units=1 [..]")
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn test_with_dev_profile() {
|
|
// The `test` profile inherits from `dev` for both local crates and
|
|
// dependencies.
|
|
Package::new("somedep", "1.0.0").publish();
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
|
|
[dependencies]
|
|
somedep = "1.0"
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.build();
|
|
p.cargo("test --lib --no-run -v")
|
|
.env("CARGO_PROFILE_DEV_DEBUG", "0")
|
|
.with_stderr(
|
|
"\
|
|
[UPDATING] [..]
|
|
[DOWNLOADING] [..]
|
|
[DOWNLOADED] [..]
|
|
[COMPILING] somedep v1.0.0
|
|
[RUNNING] `rustc --crate-name somedep [..]-C debuginfo=0[..]
|
|
[COMPILING] foo v0.1.0 [..]
|
|
[RUNNING] `rustc --crate-name foo [..]-C debuginfo=0[..]
|
|
[FINISHED] [..]
|
|
[EXECUTABLE] `[..]/target/debug/deps/foo-[..][EXE]`
|
|
",
|
|
)
|
|
.run();
|
|
}
|