Auto merge of #7823 - ehuss:stabilize-config-profile, r=alexcrichton

Stabilize config-profile.

This is a proposal to stabilize config-profiles. This feature was proposed in [RFC 2282](https://github.com/rust-lang/rfcs/pull/2282) and implemented in #5506. Tracking issue is rust-lang/rust#48683.

This is intended to land in 1.43 which will reach the stable channel on April 23rd.

This is a fairly straightforward extension of profiles where the exact same syntax from `Cargo.toml` can be specified in a config file. Environment variables are supported for everything except the `package` override table, where we do not support the ability to read arbitrary keys in the environment name.
This commit is contained in:
bors 2020-01-31 11:50:31 +00:00
commit f9132126af
8 changed files with 142 additions and 86 deletions

View file

@ -36,7 +36,6 @@ Available unstable (nightly-only) flags:
-Z minimal-versions -- Install minimal dependency versions instead of maximum
-Z no-index-update -- Do not update the registry, avoids a network request for benchmarking
-Z unstable-options -- Allow the usage of unstable options
-Z config-profile -- Read profiles from .cargo/config files
-Z timings -- Display concurrency information
-Z doctest-xcompile -- Compile and run doctests for non-host target using runner config

View file

@ -331,7 +331,6 @@ pub struct CliUnstable {
pub minimal_versions: bool,
pub package_features: bool,
pub advanced_env: bool,
pub config_profile: bool,
pub config_include: bool,
pub dual_proc_macros: bool,
pub mtime_on_use: bool,
@ -397,7 +396,6 @@ impl CliUnstable {
"minimal-versions" => self.minimal_versions = parse_empty(k, v)?,
"package-features" => self.package_features = parse_empty(k, v)?,
"advanced-env" => self.advanced_env = parse_empty(k, v)?,
"config-profile" => self.config_profile = parse_empty(k, v)?,
"config-include" => self.config_include = parse_empty(k, v)?,
"dual-proc-macros" => self.dual_proc_macros = parse_empty(k, v)?,
// can also be set in .cargo/config or with and ENV

View file

@ -908,13 +908,9 @@ fn merge_config_profiles(
};
// List of profile names to check if defined in config only.
let mut check_to_add = vec![requested_profile];
// Flag so -Zconfig-profile warning is only printed once.
let mut unstable_warned = false;
// Merge config onto manifest profiles.
for (name, profile) in &mut profiles {
if let Some(config_profile) =
get_config_profile(name, config, features, &mut unstable_warned)?
{
if let Some(config_profile) = get_config_profile(name, config, features)? {
profile.merge(&config_profile);
}
if let Some(inherits) = &profile.inherits {
@ -928,9 +924,7 @@ fn merge_config_profiles(
std::mem::swap(&mut current, &mut check_to_add);
for name in current.drain(..) {
if !profiles.contains_key(&name) {
if let Some(config_profile) =
get_config_profile(&name, config, features, &mut unstable_warned)?
{
if let Some(config_profile) = get_config_profile(&name, config, features)? {
if let Some(inherits) = &config_profile.inherits {
check_to_add.push(*inherits);
}
@ -947,20 +941,12 @@ fn get_config_profile(
name: &str,
config: &Config,
features: &Features,
unstable_warned: &mut bool,
) -> CargoResult<Option<TomlProfile>> {
let profile: Option<config::Value<TomlProfile>> = config.get(&format!("profile.{}", name))?;
let profile = match profile {
Some(profile) => profile,
None => return Ok(None),
};
if !*unstable_warned && !config.cli_unstable().config_profile {
config.shell().warn(format!(
"config profiles require the `-Z config-profile` command-line option (found profile `{}` in {})",
name, profile.definition))?;
*unstable_warned = true;
return Ok(None);
}
let mut warnings = Vec::new();
profile
.val

View file

@ -87,6 +87,21 @@ retry = 2 # network retries
git-fetch-with-cli = true # use the `git` executable for git operations
offline = false # do not access the network
[profile.<name>] # Modify profile settings via config.
opt-level = 0 # Optimization level.
debug = true # Include debug info.
debug-assertions = true # Enables debug assertions.
overflow-checks = true # Enables runtime integer overflow checks.
lto = false # Sets link-time optimization.
panic = 'unwind' # The panic strategy.
incremental = true # Incremental compilation.
codegen-units = 16 # Number of code generation units.
rpath = false # Sets the rpath linking option.
[profile.<name>.build-override] # Overrides build-script settings.
# Same keys for a normal profile.
[profile.<name>.package.<name>] # Override profile for a package.
# Same keys for a normal profile (minus `panic`, `lto`, and `rpath`).
[registries.<name>] # registries other than crates.io
index = "…" # URL of the registry index
token = "…" # authentication token for the registry
@ -549,6 +564,93 @@ needed, and generate an error if it encounters a network error.
Can be overridden with the `--offline` command-line option.
#### `[profile]`
The `[profile]` table can be used to globally change profile settings, and
override settings specified in `Cargo.toml`. It has the same syntax and
options as profiles specified in `Cargo.toml`. See the [Profiles chapter] for
details about the options.
[Profiles chapter]: profiles.md
##### `[profile.<name>.build-override]`
* Environment: `CARGO_PROFILE_<name>_BUILD_OVERRIDE_<key>`
The build-override table overrides settings for build scripts, proc macros,
and their dependencies. It has the same keys as a normal profile. See the
[overrides section](profiles.md#overrides) for more details.
##### `[profile.<name>.package.<name>]`
* Environment: not supported
The package table overrides settings for specific packages. It has the same
keys as a normal profile, minus the `panic`, `lto`, and `rpath` settings. See
the [overrides section](profiles.md#overrides) for more details.
##### `profile.<name>.codegen-units`
* Type: integer
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_CODEGEN_UNITS`
See [codegen-units](profiles.md#codegen-units).
##### `profile.<name>.debug`
* Type: integer or boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_DEBUG`
See [debug](profiles.md#debug).
##### `profile.<name>.debug-assertions`
* Type: boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_DEBUG_ASSERTIONS`
See [debug-assertions](profiles.md#debug-assertions).
##### `profile.<name>.incremental`
* Type: boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_INCREMENTAL`
See [incremental](profiles.md#incremental).
##### `profile.<name>.lto`
* Type: string or boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_LTO`
See [lto](profiles.md#lto).
##### `profile.<name>.overflow-checks`
* Type: boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_OVERFLOW_CHECKS`
See [overflow-checks](profiles.md#overflow-checks).
##### `profile.<name>.opt-level`
* Type: integer or string
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_OPT_LEVEL`
See [opt-level](profiles.md#opt-level).
##### `profile.<name>.panic`
* Type: string
* default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_PANIC`
See [panic](profiles.md#panic).
##### `profile.<name>.rpath`
* Type: boolean
* default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_RPATH`
See [rpath](profiles.md#rpath).
#### `[registries]`
The `[registries]` table is used for specifying additional [registries]. It

View file

@ -84,6 +84,16 @@ supported environment variables are:
* `CARGO_NET_RETRY` — Number of times to retry network errors, see [`net.retry`].
* `CARGO_NET_GIT_FETCH_WITH_CLI` — Enables the use of the `git` executable to fetch, see [`net.git-fetch-with-cli`].
* `CARGO_NET_OFFLINE` — Offline mode, see [`net.offline`].
* `CARGO_PROFILE_<name>_BUILD_OVERRIDE_<key>` Override build script profile, see [`profile.<name>.build-override`].
* `CARGO_PROFILE_<name>_CODEGEN_UNITS` Set code generation units, see [`profile.<name>.codegen-units`].
* `CARGO_PROFILE_<name>_DEBUG` What kind of debug info to include, see [`profile.<name>.debug`].
* `CARGO_PROFILE_<name>_DEBUG_ASSERTIONS` — Enable/disable debug assertions, see [`profile.<name>.debug-assertions`].
* `CARGO_PROFILE_<name>_INCREMENTAL` Enable/disable incremental compilation, see [`profile.<name>.incremental`].
* `CARGO_PROFILE_<name>_LTO` Link-time optimization, see [`profile.<name>.lto`].
* `CARGO_PROFILE_<name>_OVERFLOW_CHECKS` Enable/disable overflow checks, see [`profile.<name>.overflow-checks`].
* `CARGO_PROFILE_<name>_OPT_LEVEL` Set the optimization level, see [`profile.<name>.opt-level`].
* `CARGO_PROFILE_<name>_PANIC` The panic strategy to use, see [`profile.<name>.panic`].
* `CARGO_PROFILE_<name>_RPATH` The rpath linking option, see [`profile.<name>.rpath`].
* `CARGO_REGISTRIES_<name>_INDEX` — URL of a registry index, see [`registries.<name>.index`].
* `CARGO_REGISTRIES_<name>_TOKEN` — Authentication token of a registry, see [`registries.<name>.token`].
* `CARGO_REGISTRY_DEFAULT` — Default registry for the `--registry` flag, see [`registry.default`].
@ -129,6 +139,16 @@ supported environment variables are:
[`net.retry`]: config.md#netretry
[`net.git-fetch-with-cli`]: config.md#netgit-fetch-with-cli
[`net.offline`]: config.md#netoffline
[`profile.<name>.build-override`]: config.md#profilenamebuild-override
[`profile.<name>.codegen-units`]: config.md#profilenamecodegen-units
[`profile.<name>.debug`]: config.md#profilenamedebug
[`profile.<name>.debug-assertions`]: config.md#profilenamedebug-assertions
[`profile.<name>.incremental`]: config.md#profilenameincremental
[`profile.<name>.lto`]: config.md#profilenamelto
[`profile.<name>.overflow-checks`]: config.md#profilenameoverflow-checks
[`profile.<name>.opt-level`]: config.md#profilenameopt-level
[`profile.<name>.panic`]: config.md#profilenamepanic
[`profile.<name>.rpath`]: config.md#profilenamerpath
[`registries.<name>.index`]: config.md#registriesnameindex
[`registries.<name>.token`]: config.md#registriesnametoken
[`registry.default`]: config.md#registrydefault

View file

@ -22,6 +22,12 @@ Cargo only looks at the profile settings in the `Cargo.toml` manifest at the
root of the workspace. Profile settings defined in dependencies will be
ignored.
Additionally, profiles can be overridden from a [config] definition.
Specifying a profile in a config file or environment variable will override
the settings from `Cargo.toml`.
[config]: config.md
### Profile settings
The following is a list of settings that can be controlled in a profile.
@ -393,5 +399,4 @@ crates. When experimenting with optimizing dependencies for development,
consider trying opt-level 1, which will apply some optimizations while still
allowing monomorphized items to be shared.
[nalgebra]: https://crates.io/crates/nalgebra

View file

@ -158,26 +158,6 @@ lto = true
```
### Config Profiles
* Tracking Issue: [rust-lang/rust#48683](https://github.com/rust-lang/rust/issues/48683)
* RFC: [#2282](https://github.com/rust-lang/rfcs/blob/master/text/2282-profile-dependencies.md)
Profiles can be specified in `.cargo/config` files. The `-Z config-profile`
command-line flag is required to use this feature. The format is the same as
in a `Cargo.toml` manifest. If found in multiple config files, settings will
be merged using the regular [config hierarchy](config.md#hierarchical-structure).
Config settings take precedence over manifest settings.
```toml
[profile.dev]
opt-level = 3
```
```
cargo +nightly build -Z config-profile
```
### Namespaced features
* Original issue: [#1286](https://github.com/rust-lang/cargo/issues/1286)
* Tracking Issue: [#5565](https://github.com/rust-lang/cargo/issues/5565)

View file

@ -3,31 +3,6 @@
use cargo_test_support::paths::CargoPathExt;
use cargo_test_support::{basic_lib_manifest, paths, project};
#[cargo_test]
fn profile_config_gated() {
let p = project()
.file("Cargo.toml", &basic_lib_manifest("foo"))
.file("src/lib.rs", "")
.file(
".cargo/config",
r#"
[profile.dev]
debug = 1
"#,
)
.build();
p.cargo("build -v")
.with_stderr_contains(
"\
[WARNING] config profiles require the `-Z config-profile` command-line option \
(found profile `dev` in [..]/foo/.cargo/config)
",
)
.with_stderr_contains("[..]-C debuginfo=2[..]")
.run();
}
#[cargo_test]
fn named_profile_gated() {
// Named profile in config requires enabling in Cargo.toml.
@ -42,7 +17,7 @@ fn named_profile_gated() {
"#,
)
.build();
p.cargo("build --profile foo -Zunstable-options -Zconfig-profile")
p.cargo("build --profile foo -Zunstable-options")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
@ -84,8 +59,7 @@ fn profile_config_validate_warnings() {
)
.build();
p.cargo("build -Z config-profile")
.masquerade_as_nightly_cargo()
p.cargo("build")
.with_stderr_unordered(
"\
[WARNING] unused config key `profile.dev.bad-key` in `[..].cargo/config`
@ -120,8 +94,7 @@ fn profile_config_error_paths() {
)
.build();
p.cargo("build -Z config-profile")
.masquerade_as_nightly_cargo()
p.cargo("build")
.with_status(101)
.with_stderr(
"\
@ -148,8 +121,7 @@ fn profile_config_validate_errors() {
)
.build();
p.cargo("build -Z config-profile")
.masquerade_as_nightly_cargo()
p.cargo("build")
.with_status(101)
.with_stderr(
"\
@ -176,8 +148,7 @@ fn profile_config_syntax_errors() {
)
.build();
p.cargo("build -Z config-profile")
.masquerade_as_nightly_cargo()
p.cargo("build")
.with_status(101)
.with_stderr(
"\
@ -221,8 +192,7 @@ fn profile_config_override_spec_multiple() {
// Unfortunately this doesn't tell you which file, hopefully it's not too
// much of a problem.
p.cargo("build -v -Z config-profile")
.masquerade_as_nightly_cargo()
p.cargo("build -v")
.with_status(101)
.with_stderr(
"\
@ -254,8 +224,7 @@ fn profile_config_all_options() {
)
.build();
p.cargo("build --release -v -Z config-profile")
.masquerade_as_nightly_cargo()
p.cargo("build --release -v")
.env_remove("CARGO_INCREMENTAL")
.with_stderr(
"\
@ -309,8 +278,7 @@ fn profile_config_override_precedence() {
)
.build();
p.cargo("build -v -Z config-profile")
.masquerade_as_nightly_cargo()
p.cargo("build -v")
.with_stderr(
"\
[COMPILING] bar [..]
@ -336,8 +304,7 @@ fn profile_config_no_warn_unknown_override() {
)
.build();
p.cargo("build -Z config-profile")
.masquerade_as_nightly_cargo()
p.cargo("build")
.with_stderr_does_not_contain("[..]warning[..]")
.run();
}
@ -363,8 +330,7 @@ fn profile_config_mixed_types() {
)
.build();
p.cargo("build -v -Z config-profile")
.masquerade_as_nightly_cargo()
p.cargo("build -v")
.with_stderr_contains("[..]-C opt-level=3 [..]")
.run();
}
@ -406,7 +372,7 @@ fn named_config_profile() {
"#,
)
.unwrap();
let config = ConfigBuilder::new().unstable_flag("config-profile").build();
let config = ConfigBuilder::new().build();
let mut warnings = Vec::new();
let features = Features::new(&["named-profiles".to_string()], &mut warnings).unwrap();
assert_eq!(warnings.len(), 0);
@ -481,7 +447,7 @@ fn named_env_profile() {
.file("src/lib.rs", "")
.build();
p.cargo("build -v -Zconfig-profile -Zunstable-options --profile=other")
p.cargo("build -v -Zunstable-options --profile=other")
.masquerade_as_nightly_cargo()
.env("CARGO_PROFILE_OTHER_CODEGEN_UNITS", "1")
.env("CARGO_PROFILE_OTHER_INHERITS", "dev")