diff --git a/doc/book/src/reference/config.md b/doc/book/src/reference/config.md index a6389adc03f..14285378893 100644 --- a/doc/book/src/reference/config.md +++ b/doc/book/src/reference/config.md @@ -71,6 +71,7 @@ rustc-wrapper = "…" # run this wrapper instead of `rustc` rustc-workspace-wrapper = "…" # run this wrapper instead of `rustc` for workspace members rustdoc = "rustdoc" # the doc generator tool target = "triple" # build for the target triple (ignored by `cargo install`) +profile = "dev" # build using the specified profile (ignored by `cargo install`) target-dir = "target" # path of where to place generated artifacts build-dir = "target" # path of where to place intermediate build artifacts rustflags = ["…", "…"] # custom flags to pass to all compiler invocations @@ -119,6 +120,7 @@ user-agent = "…" # the user-agent header [install] root = "/some/path" # `cargo install` destination directory +profile = "release" # build using the specified profile [net] retry = 3 # network retries @@ -544,6 +546,22 @@ Can be overridden with the `--target` CLI option. target = ["x86_64-unknown-linux-gnu", "i686-unknown-linux-gnu"] ``` +#### `build.profile` +* Type: string +* Default: `"dev"` +* Environment: `CARGO_BUILD_PROFILE` + +The default [profile] to compile with. + +Can be overridden with the `--release` or `--profile` CLI options. + +```toml +[build] +profile = "debug" +``` + +> **MSRV:** Respected as of 1.100. + #### `build.target-dir` * Type: string (path) * Default: `"target"` @@ -921,6 +939,26 @@ your home directory). Can be overridden with the `--root` command-line option. +#### `install.profile` +* Type: string +* Default: `"release"` +* Environment: `CARGO_INSTALL_PROFILE` + +The default [profile] to compile with. + +Can be overridden with the `--debug` or `--profile` CLI options. + +```toml +[install] +profile = "tool" + +[profile.tool] +inherits = "release" +lto = true +``` + +> **MSRV:** Respected as of 1.100. + ### `[net]` The `[net]` table controls networking configuration. @@ -1551,6 +1589,7 @@ Report progress to the terminal emulator for display in places like the task bar [source replacement]: source-replacement.md [revision]: https://git-scm.com/docs/gitrevisions [registries]: registries.md +[profile]: profiles.md [`cargo:token`]: registry-authentication.md#cargotoken [crates.io]: https://crates.io/ [target triple]: ../appendix/glossary.md#target '"target" (glossary)' diff --git a/doc/book/src/reference/environment-variables.md b/doc/book/src/reference/environment-variables.md index ed130e472e0..214bbad878c 100644 --- a/doc/book/src/reference/environment-variables.md +++ b/doc/book/src/reference/environment-variables.md @@ -97,6 +97,7 @@ In summary, the supported environment variables are: * `CARGO_BUILD_TARGET` --- The default target platform, see [`build.target`]. * `CARGO_BUILD_TARGET_DIR` --- The default output directory, see [`build.target-dir`]. * `CARGO_BUILD_BUILD_DIR` --- The default build directory, see [`build.build-dir`]. +* `CARGO_BUILD_PROFILE` --- The default profile, see [`build.profile`]. * `CARGO_BUILD_RUSTFLAGS` --- Extra `rustc` flags, see [`build.rustflags`]. * `CARGO_BUILD_RUSTDOCFLAGS` --- Extra `rustdoc` flags, see [`build.rustdocflags`]. * `CARGO_BUILD_INCREMENTAL` --- Incremental compilation, see [`build.incremental`]. @@ -116,6 +117,7 @@ In summary, the supported environment variables are: * `CARGO_HTTP_MULTIPLEXING` --- Whether HTTP/2 multiplexing is used, see [`http.multiplexing`]. * `CARGO_HTTP_USER_AGENT` --- The HTTP user-agent header, see [`http.user-agent`]. * `CARGO_INSTALL_ROOT` --- The default directory for [`cargo install`], see [`install.root`]. +* `CARGO_INSTALL_PROFILE` --- The default profile, see [`install.profile`]. * `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`]. @@ -172,6 +174,7 @@ In summary, the supported environment variables are: [`build.target`]: config.md#buildtarget [`build.target-dir`]: config.md#buildtarget-dir [`build.build-dir`]: config.md#buildbuild-dir +[`build.profile`]: config.md#buildprofile [`build.rustflags`]: config.md#buildrustflags [`build.rustdocflags`]: config.md#buildrustdocflags [`build.incremental`]: config.md#buildincremental @@ -194,6 +197,7 @@ In summary, the supported environment variables are: [`http.multiplexing`]: config.md#httpmultiplexing [`http.user-agent`]: config.md#httpuser-agent [`install.root`]: config.md#installroot +[`install.profile`]: config.md#installprofile [`net.retry`]: config.md#netretry [`net.git-fetch-with-cli`]: config.md#netgit-fetch-with-cli [`net.offline`]: config.md#netoffline diff --git a/src/bin/cargo/commands/clean.rs b/src/bin/cargo/commands/clean.rs index a0ff63f3bb2..1ad8bcded22 100644 --- a/src/bin/cargo/commands/clean.rs +++ b/src/bin/cargo/commands/clean.rs @@ -158,11 +158,17 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult { if args.flag("workspace") { spec.extend(ws.members().map(|package| package.name().to_string())) }; + let default_profile = gctx + .build_config()? + .profile + .as_ref() + .map(|p| p.as_ref()) + .unwrap_or_else(|| "dev"); let opts = CleanOptions { gctx, spec, targets: args.targets()?, - requested_profile: args.get_profile_name("dev", ProfileChecking::Custom)?, + requested_profile: args.get_profile_name(default_profile, ProfileChecking::Custom)?, profile_specified: args.contains_id("profile") || args.flag("release"), doc: args.flag("doc"), dry_run: args.dry_run(), diff --git a/src/bin/cargo/commands/install.rs b/src/bin/cargo/commands/install.rs index bd81f5799e0..8f657ac4bdc 100644 --- a/src/bin/cargo/commands/install.rs +++ b/src/bin/cargo/commands/install.rs @@ -9,6 +9,7 @@ use cargo::util::IntoUrl; use cargo::util::VersionExt; use cargo::workspace::{GitReference, SourceId, Workspace}; use cargo_util_schemas::manifest::PackageName; +use cargo_util_schemas::manifest::ProfileName; use itertools::Itertools; use semver::VersionReq; @@ -224,8 +225,13 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult { ProfileChecking::Custom, )?; + let default_profile = gctx.get::>("install.profile")?; + let default_profile = default_profile + .as_ref() + .map(|p| p.as_ref()) + .unwrap_or_else(|| "release"); compile_opts.build_config.requested_profile = - args.get_profile_name("release", ProfileChecking::Custom)?; + args.get_profile_name(default_profile, ProfileChecking::Custom)?; if args.dry_run() { gctx.cli_unstable().fail_if_stable_opt("--dry-run", 11123)?; } diff --git a/src/bin/cargo/commands/test.rs b/src/bin/cargo/commands/test.rs index 0030ab3a71d..63a931a6efc 100644 --- a/src/bin/cargo/commands/test.rs +++ b/src/bin/cargo/commands/test.rs @@ -73,8 +73,14 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult { let mut compile_opts = args.compile_options(gctx, UserIntent::Test, Some(&ws), ProfileChecking::Custom)?; + let default_profile = gctx + .build_config()? + .profile + .as_ref() + .map(|p| p.as_ref()) + .unwrap_or_else(|| "test"); compile_opts.build_config.requested_profile = - args.get_profile_name("test", ProfileChecking::Custom)?; + args.get_profile_name(default_profile, ProfileChecking::Custom)?; // `TESTNAME` is actually an argument of the test binary, but it's // important, so we explicitly mention it and reconfigure. diff --git a/src/context/schema.rs b/src/context/schema.rs index a2ad9438c73..903de03e741 100644 --- a/src/context/schema.rs +++ b/src/context/schema.rs @@ -15,6 +15,7 @@ use std::borrow::Cow; use std::ffi::OsStr; use cargo_credential::Secret; +use cargo_util_schemas::manifest::ProfileName; use serde::Deserialize; use serde_untagged::UntaggedEnumVisitor; @@ -205,6 +206,7 @@ pub struct CargoBuildConfig { pub build_dir: Option, pub incremental: Option, pub target: Option, + pub profile: Option, pub jobs: Option, pub rustflags: Option, pub rustdocflags: Option, diff --git a/src/util/command_prelude.rs b/src/util/command_prelude.rs index e09db6eb397..ed706a81376 100644 --- a/src/util/command_prelude.rs +++ b/src/util/command_prelude.rs @@ -815,7 +815,14 @@ Run `{cmd}` to see possible targets." intent, )?; build_config.message_format = message_format.unwrap_or(MessageFormat::Human); - build_config.requested_profile = self.get_profile_name("dev", profile_checking)?; + let default_profile = gctx + .build_config()? + .profile + .as_ref() + .map(|p| p.as_ref()) + .unwrap_or_else(|| "dev"); + build_config.requested_profile = + self.get_profile_name(default_profile, profile_checking)?; build_config.unit_graph = self.flag("unit-graph"); build_config.future_incompat_report = self.flag("future-incompat-report"); build_config.compile_time_deps_only = self.flag("compile-time-deps"); diff --git a/tests/testsuite/profile_config.rs b/tests/testsuite/profile_config.rs index a422989487d..d75fdfd3f6d 100644 --- a/tests/testsuite/profile_config.rs +++ b/tests/testsuite/profile_config.rs @@ -483,3 +483,159 @@ fn named_env_profile() { "#]]) .run(); } + +#[cargo_test] +fn check_uses_build_profile() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2015" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + p.cargo("check") + .env("CARGO_BUILD_PROFILE", "release") + .with_stderr_data(str![[r#" +[CHECKING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test] +fn check_ignores_install_profile() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2015" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + p.cargo("check") + .env("CARGO_INSTALL_PROFILE", "release") + .with_stderr_data(str![[r#" +[CHECKING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test] +fn test_uses_build_profile() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2015" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + p.cargo("test --no-run") + .env("CARGO_BUILD_PROFILE", "release") + .with_stderr_data(str![[r#" +[COMPILING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s +[EXECUTABLE] unittests src/main.rs (target/release/deps/foo-[HASH][EXE]) + +"#]]) + .run(); +} + +#[cargo_test] +fn test_ignores_install_profile() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2015" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + p.cargo("test --no-run") + .env("CARGO_INSTALL_PROFILE", "release") + .with_stderr_data(str![[r#" +[COMPILING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[EXECUTABLE] unittests src/main.rs (target/debug/deps/foo-[HASH][EXE]) + +"#]]) + .run(); +} + +#[cargo_test] +fn install_uses_install_profile() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2015" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + p.cargo("install") + .env("CARGO_INSTALL_PROFILE", "debug") + .with_stderr_data(str![[r#" +[WARNING] using `cargo install` to install the binaries from the package in current working directory is deprecated, use `cargo install --path .` instead. [NOTE] use `cargo build` if you want to simply build the package. +[INSTALLING] foo v0.1.0 ([ROOT]/foo) +[COMPILING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `debug` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE] +[INSTALLED] package `foo v0.1.0 ([ROOT]/foo)` (executable `foo[EXE]`) +[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries + +"#]]) + .run(); +} + +#[cargo_test] +fn install_ignores_build_profile() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2015" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + p.cargo("install") + .env("CARGO_BUILD_PROFILE", "dev") + .with_stderr_data(str![[r#" +[WARNING] using `cargo install` to install the binaries from the package in current working directory is deprecated, use `cargo install --path .` instead. [NOTE] use `cargo build` if you want to simply build the package. +[INSTALLING] foo v0.1.0 ([ROOT]/foo) +[COMPILING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s +[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE] +[INSTALLED] package `foo v0.1.0 ([ROOT]/foo)` (executable `foo[EXE]`) +[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries + +"#]]) + .run(); +}