Skip to content

Commit

Permalink
Auto merge of #6989 - da-x:custom-profile-pr-rfc, r=ehuss
Browse files Browse the repository at this point in the history
Support for named profiles (RFC 2678)

Tracking issue: #6988

Implementation according to the [RFC](https://github.com/rust-lang/rfcs/blob/master/text/2678-named-custom-cargo-profiles.md).
  • Loading branch information
bors committed Sep 30, 2019
2 parents 8ae8b5e + fad192d commit 8b0561d
Show file tree
Hide file tree
Showing 45 changed files with 1,513 additions and 457 deletions.
13 changes: 11 additions & 2 deletions src/bin/cargo/commands/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,18 @@ Compilation can be customized with the `bench` profile in the manifest.

pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
let ws = args.workspace(config)?;
let mut compile_opts = args.compile_options(config, CompileMode::Bench, Some(&ws))?;
let mut compile_opts = args.compile_options(
config,
CompileMode::Bench,
Some(&ws),
ProfileChecking::Checked,
)?;

compile_opts.build_config.release = true;
compile_opts.build_config.profile_kind = args.get_profile_kind(
config,
ProfileKind::Custom("bench".to_owned()),
ProfileChecking::Checked,
)?;

let ops = TestOptions {
no_run: args.is_present("no-run"),
Expand Down
8 changes: 7 additions & 1 deletion src/bin/cargo/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub fn cli() -> App {
"Build all targets",
)
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
Expand Down Expand Up @@ -55,7 +56,12 @@ the --release flag will use the `release` profile instead.

pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
let ws = args.workspace(config)?;
let mut compile_opts = args.compile_options(config, CompileMode::Build, Some(&ws))?;
let mut compile_opts = args.compile_options(
config,
CompileMode::Build,
Some(&ws),
ProfileChecking::Checked,
)?;

compile_opts.export_dir = args.value_of_path("out-dir", config);
if compile_opts.export_dir.is_some() {
Expand Down
4 changes: 2 additions & 2 deletions src/bin/cargo/commands/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub fn cli() -> App {
"Check all targets",
)
.arg_release("Check artifacts in release mode, with optimizations")
.arg(opt("profile", "Profile to build the selected target for").value_name("PROFILE"))
.arg_profile("Check artifacts with the specified profile")
.arg_features()
.arg_target_triple("Check for the target triple")
.arg_target_dir()
Expand Down Expand Up @@ -69,7 +69,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
}
};
let mode = CompileMode::Check { test };
let compile_opts = args.compile_options(config, mode, Some(&ws))?;
let compile_opts = args.compile_options(config, mode, Some(&ws), ProfileChecking::Unchecked)?;

ops::compile(&ws, &compile_opts)?;
Ok(())
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub fn cli() -> App {
.arg_target_triple("Target triple to clean output for")
.arg_target_dir()
.arg_release("Whether or not to clean release artifacts")
.arg_profile("Clean artifacts of the specified profile")
.arg_doc("Whether or not to clean just the documentation directory")
.after_help(
"\
Expand All @@ -28,7 +29,8 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
config,
spec: values(args, "package"),
target: args.target(),
release: args.is_present("release"),
profile_kind: args.get_profile_kind(config, ProfileKind::Dev, ProfileChecking::Checked)?,
profile_specified: args.is_present("profile") || args.is_present("release"),
doc: args.is_present("doc"),
};
ops::clean(&ws, &opts)?;
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/clippy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub fn cli() -> App {
"Check all targets",
)
.arg_release("Check artifacts in release mode, with optimizations")
.arg_profile("Check artifacts with the specified profile")
.arg_features()
.arg_target_triple("Check for the target triple")
.arg_target_dir()
Expand Down Expand Up @@ -61,7 +62,8 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
let ws = args.workspace(config)?;

let mode = CompileMode::Check { test: false };
let mut compile_opts = args.compile_options(config, mode, Some(&ws))?;
let mut compile_opts =
args.compile_options(config, mode, Some(&ws), ProfileChecking::Checked)?;

if !config.cli_unstable().unstable_options {
return Err(failure::format_err!(
Expand Down
4 changes: 3 additions & 1 deletion src/bin/cargo/commands/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub fn cli() -> App {
"Document all binaries",
)
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
Expand Down Expand Up @@ -52,7 +53,8 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
let mode = CompileMode::Doc {
deps: !args.is_present("no-deps"),
};
let mut compile_opts = args.compile_options(config, mode, Some(&ws))?;
let mut compile_opts =
args.compile_options(config, mode, Some(&ws), ProfileChecking::Checked)?;
compile_opts.local_rustdoc_args = if args.is_present("document-private-items") {
Some(vec!["--document-private-items".to_string()])
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/bin/cargo/commands/fix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub fn cli() -> App {
"Fix all targets (default)",
)
.arg_release("Fix artifacts in release mode, with optimizations")
.arg(opt("profile", "Profile to build the selected target for").value_name("PROFILE"))
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Fix for the target triple")
.arg_target_dir()
Expand Down Expand Up @@ -132,7 +132,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {

// Unlike other commands default `cargo fix` to all targets to fix as much
// code as we can.
let mut opts = args.compile_options(config, mode, Some(&ws))?;
let mut opts = args.compile_options(config, mode, Some(&ws), ProfileChecking::Unchecked)?;

let use_clippy = args.is_present("clippy");

Expand Down
13 changes: 10 additions & 3 deletions src/bin/cargo/commands/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub fn cli() -> App {
"Do not save tracking information (unstable)",
))
.arg_features()
.arg_profile("Install artifacts with from the specified profile")
.arg(opt("debug", "Build in debug mode instead of release mode"))
.arg_targets_bins_examples(
"Install only the specified binary",
Expand Down Expand Up @@ -115,9 +116,15 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
}

let workspace = args.workspace(config).ok();
let mut compile_opts = args.compile_options(config, CompileMode::Build, workspace.as_ref())?;

compile_opts.build_config.release = !args.is_present("debug");
let mut compile_opts = args.compile_options(
config,
CompileMode::Build,
workspace.as_ref(),
ProfileChecking::Checked,
)?;

compile_opts.build_config.profile_kind =
args.get_profile_kind(config, ProfileKind::Release, ProfileChecking::Checked)?;

let krates = args
.values_of("crate")
Expand Down
8 changes: 7 additions & 1 deletion src/bin/cargo/commands/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub fn cli() -> App {
.arg_package("Package with the target to run")
.arg_jobs()
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
Expand All @@ -40,7 +41,12 @@ run. If you're passing arguments to both Cargo and the binary, the ones after
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
let ws = args.workspace(config)?;

let mut compile_opts = args.compile_options(config, CompileMode::Build, Some(&ws))?;
let mut compile_opts = args.compile_options(
config,
CompileMode::Build,
Some(&ws),
ProfileChecking::Checked,
)?;

if !args.is_present("example") && !args.is_present("bin") {
let default_runs: Vec<_> = compile_opts
Expand Down
9 changes: 7 additions & 2 deletions src/bin/cargo/commands/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub fn cli() -> App {
"Build all targets",
)
.arg_release("Build artifacts in release mode, with optimizations")
.arg(opt("profile", "Profile to build the selected target for").value_name("PROFILE"))
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Target triple which compiles will be for")
.arg_target_dir()
Expand Down Expand Up @@ -63,7 +63,12 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
return Err(CliError::new(err, 101));
}
};
let mut compile_opts = args.compile_options_for_single_package(config, mode, Some(&ws))?;
let mut compile_opts = args.compile_options_for_single_package(
config,
mode,
Some(&ws),
ProfileChecking::Unchecked,
)?;
let target_args = values(args, "args");
compile_opts.target_rustc_args = if target_args.is_empty() {
None
Expand Down
2 changes: 2 additions & 0 deletions src/bin/cargo/commands/rustdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub fn cli() -> App {
"Build all targets",
)
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
Expand Down Expand Up @@ -55,6 +56,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
config,
CompileMode::Doc { deps: false },
Some(&ws),
ProfileChecking::Checked,
)?;
let target_args = values(args, "args");
compile_opts.target_rustdoc_args = if target_args.is_empty() {
Expand Down
14 changes: 13 additions & 1 deletion src/bin/cargo/commands/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub fn cli() -> App {
)
.arg_jobs()
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
Expand Down Expand Up @@ -99,7 +100,18 @@ To get the list of all options available for the test binaries use this:
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
let ws = args.workspace(config)?;

let mut compile_opts = args.compile_options(config, CompileMode::Test, Some(&ws))?;
let mut compile_opts = args.compile_options(
config,
CompileMode::Test,
Some(&ws),
ProfileChecking::Checked,
)?;

compile_opts.build_config.profile_kind = args.get_profile_kind(
config,
ProfileKind::Custom("test".to_owned()),
ProfileChecking::Checked,
)?;

// `TESTNAME` is actually an argument of the test binary, but it's
// important, so we explicitly mention it and reconfigure.
Expand Down
27 changes: 24 additions & 3 deletions src/cargo/core/compiler/build_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,32 @@ use crate::core::compiler::{CompileKind, CompileTarget};
use crate::util::ProcessBuilder;
use crate::util::{CargoResult, Config, RustfixDiagnosticServer};

#[derive(Debug, Clone)]
pub enum ProfileKind {
Dev,
Release,
Custom(String),
}

impl ProfileKind {
pub fn name(&self) -> &str {
match self {
ProfileKind::Dev => "dev",
ProfileKind::Release => "release",
ProfileKind::Custom(name) => &name,
}
}
}

/// Configuration information for a rustc build.
#[derive(Debug)]
pub struct BuildConfig {
/// The requested kind of compilation for this session
pub requested_kind: CompileKind,
/// Number of rustc jobs to run in parallel.
pub jobs: u32,
/// `true` if we are building for release.
pub release: bool,
/// Build profile
pub profile_kind: ProfileKind,
/// The mode we are compiling in.
pub mode: CompileMode,
/// `true` to print stdout in JSON format (for machine reading).
Expand Down Expand Up @@ -77,7 +94,7 @@ impl BuildConfig {
Ok(BuildConfig {
requested_kind,
jobs,
release: false,
profile_kind: ProfileKind::Dev,
mode,
message_format: MessageFormat::Human,
force_rebuild: false,
Expand All @@ -102,6 +119,10 @@ impl BuildConfig {
}
}

pub fn profile_name(&self) -> &str {
self.profile_kind.name()
}

pub fn test(&self) -> bool {
self.mode == CompileMode::Test || self.mode == CompileMode::Bench
}
Expand Down
11 changes: 4 additions & 7 deletions src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,15 +298,12 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
export_dir: Option<PathBuf>,
units: &[Unit<'a>],
) -> CargoResult<()> {
let dest = if self.bcx.build_config.release {
"release"
} else {
"debug"
};
let host_layout = Layout::new(self.bcx.ws, None, dest)?;
let profile_kind = &self.bcx.build_config.profile_kind;
let dest = self.bcx.profiles.get_dir_name(profile_kind);
let host_layout = Layout::new(self.bcx.ws, None, &dest)?;
let mut targets = HashMap::new();
if let CompileKind::Target(target) = self.bcx.build_config.requested_kind {
let layout = Layout::new(self.bcx.ws, Some(target), dest)?;
let layout = Layout::new(self.bcx.ws, Some(target), &dest)?;
standard_lib::prepare_sysroot(&layout)?;
targets.insert(target, layout);
}
Expand Down
9 changes: 4 additions & 5 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::str;
use std::sync::Arc;

use crate::core::compiler::job_queue::JobState;
use crate::core::PackageId;
use crate::core::{profiles::ProfileRoot, PackageId};
use crate::util::errors::{CargoResult, CargoResultExt};
use crate::util::machine_message::{self, Message};
use crate::util::{self, internal, paths, profile};
Expand Down Expand Up @@ -163,10 +163,9 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
.env("OPT_LEVEL", &unit.profile.opt_level.to_string())
.env(
"PROFILE",
if bcx.build_config.release {
"release"
} else {
"debug"
match unit.profile.root {
ProfileRoot::Release => "release",
ProfileRoot::Debug => "debug",
},
)
.env("HOST", &bcx.host_triple())
Expand Down
9 changes: 5 additions & 4 deletions src/cargo/core/compiler/job_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use super::job::{
use super::standard_lib;
use super::timings::Timings;
use super::{BuildContext, BuildPlan, CompileMode, Context, Unit};
use crate::core::compiler::ProfileKind;
use crate::core::{PackageId, TargetKind};
use crate::handle_error;
use crate::util;
Expand All @@ -41,10 +42,10 @@ pub struct JobQueue<'a, 'cfg> {
compiled: HashSet<PackageId>,
documented: HashSet<PackageId>,
counts: HashMap<PackageId, usize>,
is_release: bool,
progress: Progress<'cfg>,
next_id: u32,
timings: Timings<'a, 'cfg>,
profile_kind: ProfileKind,
}

pub struct JobState<'a> {
Expand Down Expand Up @@ -145,10 +146,10 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
compiled: HashSet::new(),
documented: HashSet::new(),
counts: HashMap::new(),
is_release: bcx.build_config.release,
progress,
next_id: 0,
timings,
profile_kind: bcx.build_config.profile_kind.clone(),
}
}

Expand Down Expand Up @@ -416,15 +417,15 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
}
self.progress.clear();

let build_type = if self.is_release { "release" } else { "dev" };
let build_type = self.profile_kind.name();
// NOTE: this may be a bit inaccurate, since this may not display the
// profile for what was actually built. Profile overrides can change
// these settings, and in some cases different targets are built with
// different profiles. To be accurate, it would need to collect a
// list of Units built, and maybe display a list of the different
// profiles used. However, to keep it simple and compatible with old
// behavior, we just display what the base profile is.
let profile = cx.bcx.profiles.base_profile(self.is_release);
let profile = cx.bcx.profiles.base_profile(&self.profile_kind)?;
let mut opt_type = String::from(if profile.opt_level.as_str() == "0" {
"unoptimized"
} else {
Expand Down

0 comments on commit 8b0561d

Please sign in to comment.