mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Add named config profiles.
This commit is contained in:
parent
56a5503268
commit
77ee608de3
@ -1,5 +1,4 @@
|
||||
use crate::command_prelude::*;
|
||||
|
||||
use cargo::ops::{self, TestOptions};
|
||||
|
||||
pub fn cli() -> App {
|
||||
@ -80,11 +79,8 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
|
||||
ProfileChecking::Checked,
|
||||
)?;
|
||||
|
||||
compile_opts.build_config.profile_kind = args.get_profile_kind(
|
||||
config,
|
||||
ProfileKind::Custom("bench".to_owned()),
|
||||
ProfileChecking::Checked,
|
||||
)?;
|
||||
compile_opts.build_config.requested_profile =
|
||||
args.get_profile_name(config, "bench", ProfileChecking::Checked)?;
|
||||
|
||||
let ops = TestOptions {
|
||||
no_run: args.is_present("no-run"),
|
||||
|
@ -29,7 +29,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
|
||||
config,
|
||||
spec: values(args, "package"),
|
||||
target: args.target(),
|
||||
profile_kind: args.get_profile_kind(config, ProfileKind::Dev, ProfileChecking::Checked)?,
|
||||
requested_profile: args.get_profile_name(config, "dev", ProfileChecking::Checked)?,
|
||||
profile_specified: args.is_present("profile") || args.is_present("release"),
|
||||
doc: args.is_present("doc"),
|
||||
};
|
||||
|
@ -116,8 +116,8 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
|
||||
ProfileChecking::Checked,
|
||||
)?;
|
||||
|
||||
compile_opts.build_config.profile_kind =
|
||||
args.get_profile_kind(config, ProfileKind::Release, ProfileChecking::Checked)?;
|
||||
compile_opts.build_config.requested_profile =
|
||||
args.get_profile_name(config, "release", ProfileChecking::Checked)?;
|
||||
|
||||
let krates = args
|
||||
.values_of("crate")
|
||||
|
@ -108,11 +108,8 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
|
||||
ProfileChecking::Checked,
|
||||
)?;
|
||||
|
||||
compile_opts.build_config.profile_kind = args.get_profile_kind(
|
||||
config,
|
||||
ProfileKind::Custom("test".to_owned()),
|
||||
ProfileChecking::Checked,
|
||||
)?;
|
||||
compile_opts.build_config.requested_profile =
|
||||
args.get_profile_name(config, "test", ProfileChecking::Checked)?;
|
||||
|
||||
// `TESTNAME` is actually an argument of the test binary, but it's
|
||||
// important, so we explicitly mention it and reconfigure.
|
||||
|
@ -1,27 +1,9 @@
|
||||
use std::cell::RefCell;
|
||||
|
||||
use serde::ser;
|
||||
|
||||
use crate::core::compiler::{CompileKind, CompileTarget};
|
||||
use crate::core::interning::InternedString;
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
use serde::ser;
|
||||
use std::cell::RefCell;
|
||||
|
||||
/// Configuration information for a rustc build.
|
||||
#[derive(Debug)]
|
||||
@ -31,7 +13,7 @@ pub struct BuildConfig {
|
||||
/// Number of rustc jobs to run in parallel.
|
||||
pub jobs: u32,
|
||||
/// Build profile
|
||||
pub profile_kind: ProfileKind,
|
||||
pub requested_profile: InternedString,
|
||||
/// The mode we are compiling in.
|
||||
pub mode: CompileMode,
|
||||
/// `true` to print stdout in JSON format (for machine reading).
|
||||
@ -92,7 +74,7 @@ impl BuildConfig {
|
||||
Ok(BuildConfig {
|
||||
requested_kind,
|
||||
jobs,
|
||||
profile_kind: ProfileKind::Dev,
|
||||
requested_profile: InternedString::new("dev"),
|
||||
mode,
|
||||
message_format: MessageFormat::Human,
|
||||
force_rebuild: false,
|
||||
@ -111,10 +93,6 @@ 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
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ pub struct BuildContext<'a, 'cfg> {
|
||||
pub ws: &'a Workspace<'cfg>,
|
||||
/// The cargo configuration.
|
||||
pub config: &'cfg Config,
|
||||
pub profiles: &'a Profiles,
|
||||
pub profiles: Profiles,
|
||||
pub build_config: &'a BuildConfig,
|
||||
/// Extra compiler args for either `rustc` or `rustdoc`.
|
||||
pub extra_compiler_args: HashMap<Unit<'a>, Vec<String>>,
|
||||
@ -58,7 +58,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
|
||||
packages: &'a PackageSet<'cfg>,
|
||||
config: &'cfg Config,
|
||||
build_config: &'a BuildConfig,
|
||||
profiles: &'a Profiles,
|
||||
profiles: Profiles,
|
||||
units: &'a UnitInterner<'a>,
|
||||
extra_compiler_args: HashMap<Unit<'a>, Vec<String>>,
|
||||
) -> CargoResult<BuildContext<'a, 'cfg>> {
|
||||
|
@ -281,8 +281,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
|
||||
export_dir: Option<PathBuf>,
|
||||
units: &[Unit<'a>],
|
||||
) -> CargoResult<()> {
|
||||
let profile_kind = &self.bcx.build_config.profile_kind;
|
||||
let dest = self.bcx.profiles.get_dir_name(profile_kind);
|
||||
let dest = self.bcx.profiles.get_dir_name();
|
||||
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 {
|
||||
|
@ -19,7 +19,6 @@ use super::job::{
|
||||
};
|
||||
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;
|
||||
@ -44,7 +43,6 @@ pub struct JobQueue<'a, 'cfg> {
|
||||
progress: Progress<'cfg>,
|
||||
next_id: u32,
|
||||
timings: Timings<'a, 'cfg>,
|
||||
profile_kind: ProfileKind,
|
||||
}
|
||||
|
||||
pub struct JobState<'a> {
|
||||
@ -148,7 +146,6 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
|
||||
progress,
|
||||
next_id: 0,
|
||||
timings,
|
||||
profile_kind: bcx.build_config.profile_kind.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -415,7 +412,7 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
|
||||
}
|
||||
self.progress.clear();
|
||||
|
||||
let build_type = self.profile_kind.name();
|
||||
let profile_name = cx.bcx.build_config.requested_profile;
|
||||
// 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
|
||||
@ -423,7 +420,7 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
|
||||
// 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.profile_kind)?;
|
||||
let profile = cx.bcx.profiles.base_profile();
|
||||
let mut opt_type = String::from(if profile.opt_level.as_str() == "0" {
|
||||
"unoptimized"
|
||||
} else {
|
||||
@ -440,7 +437,7 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
|
||||
} else if self.queue.is_empty() && queue.is_empty() {
|
||||
let message = format!(
|
||||
"{} [{}] target(s) in {}",
|
||||
build_type, opt_type, time_elapsed
|
||||
profile_name, opt_type, time_elapsed
|
||||
);
|
||||
if !cx.bcx.build_config.build_plan {
|
||||
cx.bcx.config.shell().status("Finished", message)?;
|
||||
|
@ -27,7 +27,7 @@ use anyhow::Error;
|
||||
use lazycell::LazyCell;
|
||||
use log::debug;
|
||||
|
||||
pub use self::build_config::{BuildConfig, CompileMode, MessageFormat, ProfileKind};
|
||||
pub use self::build_config::{BuildConfig, CompileMode, MessageFormat};
|
||||
pub use self::build_context::{BuildContext, FileFlavor, TargetInfo};
|
||||
use self::build_plan::BuildPlan;
|
||||
pub use self::compilation::{Compilation, Doctest};
|
||||
|
@ -66,8 +66,7 @@ pub fn resolve_std<'cfg>(
|
||||
/*replace*/ Vec::new(),
|
||||
patch,
|
||||
ws_config,
|
||||
// Profiles are not used here, but we need something to pass in.
|
||||
ws.profiles().clone(),
|
||||
/*profiles*/ None,
|
||||
crate::core::Features::default(),
|
||||
);
|
||||
|
||||
@ -139,7 +138,6 @@ pub fn generate_std_roots<'a>(
|
||||
/*is_member*/ false,
|
||||
unit_for,
|
||||
mode,
|
||||
bcx.build_config.profile_kind.clone(),
|
||||
);
|
||||
let features = std_resolve.features_sorted(pkg.package_id());
|
||||
Ok(bcx.units.intern(
|
||||
|
@ -116,7 +116,7 @@ impl<'a, 'cfg> Timings<'a, 'cfg> {
|
||||
})
|
||||
.collect();
|
||||
let start_str = humantime::format_rfc3339_seconds(SystemTime::now()).to_string();
|
||||
let profile = bcx.build_config.profile_kind.name().to_owned();
|
||||
let profile = bcx.build_config.requested_profile.to_string();
|
||||
|
||||
Timings {
|
||||
config: bcx.config,
|
||||
|
@ -546,7 +546,6 @@ fn new_unit_dep<'a>(
|
||||
state.bcx.ws.is_member(pkg),
|
||||
unit_for,
|
||||
mode,
|
||||
state.bcx.build_config.profile_kind.clone(),
|
||||
);
|
||||
new_unit_dep_with_profile(state, parent, pkg, target, unit_for, kind, mode, profile)
|
||||
}
|
||||
|
@ -48,6 +48,18 @@ impl PartialEq for InternedString {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<str> for InternedString {
|
||||
fn eq(&self, other: &str) -> bool {
|
||||
*self == other
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PartialEq<&'a str> for InternedString {
|
||||
fn eq(&self, other: &&str) -> bool {
|
||||
**self == **other
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for InternedString {}
|
||||
|
||||
impl InternedString {
|
||||
|
@ -10,11 +10,10 @@ use serde::Serialize;
|
||||
use url::Url;
|
||||
|
||||
use crate::core::interning::InternedString;
|
||||
use crate::core::profiles::Profiles;
|
||||
use crate::core::{Dependency, PackageId, PackageIdSpec, SourceId, Summary};
|
||||
use crate::core::{Edition, Feature, Features, WorkspaceConfig};
|
||||
use crate::util::errors::*;
|
||||
use crate::util::toml::TomlManifest;
|
||||
use crate::util::toml::{TomlManifest, TomlProfiles};
|
||||
use crate::util::{short_hash, Config, Filesystem};
|
||||
|
||||
pub enum EitherManifest {
|
||||
@ -33,7 +32,7 @@ pub struct Manifest {
|
||||
include: Vec<String>,
|
||||
metadata: ManifestMetadata,
|
||||
custom_metadata: Option<toml::Value>,
|
||||
profiles: Profiles,
|
||||
profiles: Option<TomlProfiles>,
|
||||
publish: Option<Vec<String>>,
|
||||
publish_lockfile: bool,
|
||||
replace: Vec<(PackageIdSpec, Dependency)>,
|
||||
@ -64,7 +63,7 @@ pub struct VirtualManifest {
|
||||
replace: Vec<(PackageIdSpec, Dependency)>,
|
||||
patch: HashMap<Url, Vec<Dependency>>,
|
||||
workspace: WorkspaceConfig,
|
||||
profiles: Profiles,
|
||||
profiles: Option<TomlProfiles>,
|
||||
warnings: Warnings,
|
||||
features: Features,
|
||||
}
|
||||
@ -399,7 +398,7 @@ impl Manifest {
|
||||
links: Option<String>,
|
||||
metadata: ManifestMetadata,
|
||||
custom_metadata: Option<toml::Value>,
|
||||
profiles: Profiles,
|
||||
profiles: Option<TomlProfiles>,
|
||||
publish: Option<Vec<String>>,
|
||||
publish_lockfile: bool,
|
||||
replace: Vec<(PackageIdSpec, Dependency)>,
|
||||
@ -475,8 +474,8 @@ impl Manifest {
|
||||
pub fn warnings(&self) -> &Warnings {
|
||||
&self.warnings
|
||||
}
|
||||
pub fn profiles(&self) -> &Profiles {
|
||||
&self.profiles
|
||||
pub fn profiles(&self) -> Option<&TomlProfiles> {
|
||||
self.profiles.as_ref()
|
||||
}
|
||||
pub fn publish(&self) -> &Option<Vec<String>> {
|
||||
&self.publish
|
||||
@ -563,7 +562,7 @@ impl VirtualManifest {
|
||||
replace: Vec<(PackageIdSpec, Dependency)>,
|
||||
patch: HashMap<Url, Vec<Dependency>>,
|
||||
workspace: WorkspaceConfig,
|
||||
profiles: Profiles,
|
||||
profiles: Option<TomlProfiles>,
|
||||
features: Features,
|
||||
) -> VirtualManifest {
|
||||
VirtualManifest {
|
||||
@ -588,8 +587,8 @@ impl VirtualManifest {
|
||||
&self.workspace
|
||||
}
|
||||
|
||||
pub fn profiles(&self) -> &Profiles {
|
||||
&self.profiles
|
||||
pub fn profiles(&self) -> Option<&TomlProfiles> {
|
||||
self.profiles.as_ref()
|
||||
}
|
||||
|
||||
pub fn warnings_mut(&mut self) -> &mut Warnings {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,6 @@ use log::debug;
|
||||
use url::Url;
|
||||
|
||||
use crate::core::features::Features;
|
||||
use crate::core::profiles::Profiles;
|
||||
use crate::core::registry::PackageRegistry;
|
||||
use crate::core::{Dependency, PackageId, PackageIdSpec};
|
||||
use crate::core::{EitherManifest, Package, SourceId, VirtualManifest};
|
||||
@ -17,7 +16,7 @@ use crate::ops;
|
||||
use crate::sources::PathSource;
|
||||
use crate::util::errors::{CargoResult, CargoResultExt, ManifestError};
|
||||
use crate::util::paths;
|
||||
use crate::util::toml::read_manifest;
|
||||
use crate::util::toml::{read_manifest, TomlProfiles};
|
||||
use crate::util::{Config, Filesystem};
|
||||
|
||||
/// The core abstraction in Cargo for working with a workspace of crates.
|
||||
@ -273,7 +272,7 @@ impl<'cfg> Workspace<'cfg> {
|
||||
self.config
|
||||
}
|
||||
|
||||
pub fn profiles(&self) -> &Profiles {
|
||||
pub fn profiles(&self) -> Option<&TomlProfiles> {
|
||||
match self.root_maybe() {
|
||||
MaybePackage::Package(p) => p.manifest().profiles(),
|
||||
MaybePackage::Virtual(vm) => vm.profiles(),
|
||||
@ -583,14 +582,6 @@ impl<'cfg> Workspace<'cfg> {
|
||||
/// 2. All workspace members agree on this one root as the root.
|
||||
/// 3. The current crate is a member of this workspace.
|
||||
fn validate(&mut self) -> CargoResult<()> {
|
||||
// Validate config profiles only once per workspace.
|
||||
let features = self.features();
|
||||
let mut warnings = Vec::new();
|
||||
self.config.profiles()?.validate(features, &mut warnings)?;
|
||||
for warning in warnings {
|
||||
self.config.shell().warn(&warning)?;
|
||||
}
|
||||
|
||||
// The rest of the checks require a VirtualManifest or multiple members.
|
||||
if self.root_manifest.is_none() {
|
||||
return Ok(());
|
||||
|
@ -1,13 +1,12 @@
|
||||
use crate::core::InternedString;
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::core::compiler::unit_dependencies;
|
||||
use crate::core::compiler::UnitInterner;
|
||||
use crate::core::compiler::{
|
||||
BuildConfig, BuildContext, CompileKind, CompileMode, Context, ProfileKind,
|
||||
};
|
||||
use crate::core::profiles::UnitFor;
|
||||
use crate::core::compiler::{BuildConfig, BuildContext, CompileKind, CompileMode, Context};
|
||||
use crate::core::profiles::{Profiles, UnitFor};
|
||||
use crate::core::Workspace;
|
||||
use crate::ops;
|
||||
use crate::util::errors::{CargoResult, CargoResultExt};
|
||||
@ -23,7 +22,7 @@ pub struct CleanOptions<'a> {
|
||||
/// Whether to clean the release directory
|
||||
pub profile_specified: bool,
|
||||
/// Whether to clean the directory of a certain build profile
|
||||
pub profile_kind: ProfileKind,
|
||||
pub requested_profile: InternedString,
|
||||
/// Whether to just clean the doc directory
|
||||
pub doc: bool,
|
||||
}
|
||||
@ -39,16 +38,13 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
|
||||
return rm_rf(&target_dir.into_path_unlocked(), config);
|
||||
}
|
||||
|
||||
let profiles = ws.profiles();
|
||||
|
||||
// Check for whether the profile is defined.
|
||||
let _ = profiles.base_profile(&opts.profile_kind)?;
|
||||
let profiles = Profiles::new(ws.profiles(), config, opts.requested_profile, ws.features())?;
|
||||
|
||||
if opts.profile_specified {
|
||||
// After parsing profiles we know the dir-name of the profile, if a profile
|
||||
// was passed from the command line. If so, delete only the directory of
|
||||
// that profile.
|
||||
let dir_name = profiles.get_dir_name(&opts.profile_kind);
|
||||
let dir_name = profiles.get_dir_name();
|
||||
target_dir = target_dir.join(dir_name);
|
||||
}
|
||||
|
||||
@ -64,8 +60,7 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
|
||||
|
||||
let interner = UnitInterner::new();
|
||||
let mut build_config = BuildConfig::new(config, Some(1), &opts.target, CompileMode::Build)?;
|
||||
let profile_kind = opts.profile_kind.clone();
|
||||
build_config.profile_kind = profile_kind.clone();
|
||||
build_config.requested_profile = opts.requested_profile;
|
||||
let bcx = BuildContext::new(
|
||||
ws,
|
||||
&packages,
|
||||
@ -88,20 +83,19 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
|
||||
for mode in CompileMode::all_modes() {
|
||||
for unit_for in UnitFor::all_values() {
|
||||
let profile = if mode.is_run_custom_build() {
|
||||
profiles.get_profile_run_custom_build(&profiles.get_profile(
|
||||
pkg.package_id(),
|
||||
ws.is_member(pkg),
|
||||
*unit_for,
|
||||
CompileMode::Build,
|
||||
profile_kind.clone(),
|
||||
))
|
||||
bcx.profiles
|
||||
.get_profile_run_custom_build(&bcx.profiles.get_profile(
|
||||
pkg.package_id(),
|
||||
ws.is_member(pkg),
|
||||
*unit_for,
|
||||
CompileMode::Build,
|
||||
))
|
||||
} else {
|
||||
profiles.get_profile(
|
||||
bcx.profiles.get_profile(
|
||||
pkg.package_id(),
|
||||
ws.is_member(pkg),
|
||||
*unit_for,
|
||||
*mode,
|
||||
profile_kind.clone(),
|
||||
)
|
||||
};
|
||||
let features = resolve.features_sorted(pkg.package_id());
|
||||
|
@ -300,10 +300,12 @@ pub fn compile_ws<'a>(
|
||||
}
|
||||
}
|
||||
|
||||
let profiles = ws.profiles();
|
||||
|
||||
// Early check for whether the profile is defined.
|
||||
let _ = profiles.base_profile(&build_config.profile_kind)?;
|
||||
let profiles = Profiles::new(
|
||||
ws.profiles(),
|
||||
config,
|
||||
build_config.requested_profile,
|
||||
ws.features(),
|
||||
)?;
|
||||
|
||||
let specs = spec.to_package_id_specs(ws)?;
|
||||
let dev_deps = ws.require_optional_deps() || filter.need_dev_deps(build_config.mode);
|
||||
@ -381,6 +383,7 @@ pub fn compile_ws<'a>(
|
||||
}
|
||||
|
||||
profiles.validate_packages(
|
||||
ws.profiles(),
|
||||
&mut config.shell(),
|
||||
workspace_resolve.as_ref().unwrap_or(&resolve),
|
||||
)?;
|
||||
@ -397,7 +400,6 @@ pub fn compile_ws<'a>(
|
||||
)?;
|
||||
let units = generate_targets(
|
||||
ws,
|
||||
profiles,
|
||||
&to_builds,
|
||||
filter,
|
||||
build_config.requested_kind,
|
||||
@ -652,7 +654,6 @@ struct Proposal<'a> {
|
||||
/// compile. Dependencies for these targets are computed later in `unit_dependencies`.
|
||||
fn generate_targets<'a>(
|
||||
ws: &Workspace<'_>,
|
||||
profiles: &Profiles,
|
||||
packages: &[&'a Package],
|
||||
filter: &CompileFilter,
|
||||
default_arch_kind: CompileKind,
|
||||
@ -716,13 +717,9 @@ fn generate_targets<'a>(
|
||||
_ => target_mode,
|
||||
};
|
||||
let kind = default_arch_kind.for_target(target);
|
||||
let profile = profiles.get_profile(
|
||||
pkg.package_id(),
|
||||
ws.is_member(pkg),
|
||||
unit_for,
|
||||
target_mode,
|
||||
bcx.build_config.profile_kind.clone(),
|
||||
);
|
||||
let profile =
|
||||
bcx.profiles
|
||||
.get_profile(pkg.package_id(), ws.is_member(pkg), unit_for, target_mode);
|
||||
let features = resolve.features_sorted(pkg.package_id());
|
||||
bcx.units.intern(
|
||||
pkg,
|
||||
|
@ -427,7 +427,7 @@ impl CrateListingV2 {
|
||||
info.features = feature_set(&opts.features);
|
||||
info.all_features = opts.all_features;
|
||||
info.no_default_features = opts.no_default_features;
|
||||
info.profile = opts.build_config.profile_name().to_string();
|
||||
info.profile = opts.build_config.requested_profile.to_string();
|
||||
info.target = Some(target.to_string());
|
||||
info.rustc = Some(rustc.to_string());
|
||||
} else {
|
||||
@ -439,7 +439,7 @@ impl CrateListingV2 {
|
||||
features: feature_set(&opts.features),
|
||||
all_features: opts.all_features,
|
||||
no_default_features: opts.no_default_features,
|
||||
profile: opts.build_config.profile_name().to_string(),
|
||||
profile: opts.build_config.requested_profile.to_string(),
|
||||
target: Some(target.to_string()),
|
||||
rustc: Some(rustc.to_string()),
|
||||
other: BTreeMap::new(),
|
||||
@ -499,7 +499,7 @@ impl InstallInfo {
|
||||
self.features == feature_set(&opts.features)
|
||||
&& self.all_features == opts.all_features
|
||||
&& self.no_default_features == opts.no_default_features
|
||||
&& self.profile == opts.build_config.profile_name()
|
||||
&& self.profile.as_str() == opts.build_config.requested_profile.as_str()
|
||||
&& (self.target.is_none() || self.target.as_ref().map(|t| t.as_ref()) == Some(target))
|
||||
&& &self.bins == exes
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::core::compiler::{BuildConfig, MessageFormat};
|
||||
use crate::core::InternedString;
|
||||
use crate::core::Workspace;
|
||||
use crate::ops::{CompileFilter, CompileOptions, NewOptions, Packages, VersionControl};
|
||||
use crate::sources::CRATES_IO_REGISTRY;
|
||||
@ -15,7 +16,7 @@ use std::ffi::{OsStr, OsString};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub use crate::core::compiler::{CompileMode, ProfileKind};
|
||||
pub use crate::core::compiler::CompileMode;
|
||||
pub use crate::{CliError, CliResult, Config};
|
||||
pub use clap::{AppSettings, Arg, ArgMatches};
|
||||
|
||||
@ -307,19 +308,17 @@ pub trait ArgMatchesExt {
|
||||
self._value_of("target").map(|s| s.to_string())
|
||||
}
|
||||
|
||||
fn get_profile_kind(
|
||||
fn get_profile_name(
|
||||
&self,
|
||||
config: &Config,
|
||||
default: ProfileKind,
|
||||
default: &str,
|
||||
profile_checking: ProfileChecking,
|
||||
) -> CargoResult<ProfileKind> {
|
||||
) -> CargoResult<InternedString> {
|
||||
let specified_profile = match self._value_of("profile") {
|
||||
None => None,
|
||||
Some("dev") => Some(ProfileKind::Dev),
|
||||
Some("release") => Some(ProfileKind::Release),
|
||||
Some(name) => {
|
||||
TomlProfile::validate_name(name, "profile name")?;
|
||||
Some(ProfileKind::Custom(name.to_string()))
|
||||
Some(InternedString::new(name))
|
||||
}
|
||||
};
|
||||
|
||||
@ -334,24 +333,28 @@ pub trait ArgMatchesExt {
|
||||
|
||||
if self._is_present("release") {
|
||||
if !config.cli_unstable().unstable_options {
|
||||
Ok(ProfileKind::Release)
|
||||
Ok(InternedString::new("release"))
|
||||
} else {
|
||||
match specified_profile {
|
||||
None | Some(ProfileKind::Release) => Ok(ProfileKind::Release),
|
||||
_ => anyhow::bail!("Conflicting usage of --profile and --release"),
|
||||
Some(name) if name != "release" => {
|
||||
anyhow::bail!("Conflicting usage of --profile and --release")
|
||||
}
|
||||
_ => Ok(InternedString::new("release")),
|
||||
}
|
||||
}
|
||||
} else if self._is_present("debug") {
|
||||
if !config.cli_unstable().unstable_options {
|
||||
Ok(ProfileKind::Dev)
|
||||
Ok(InternedString::new("dev"))
|
||||
} else {
|
||||
match specified_profile {
|
||||
None | Some(ProfileKind::Dev) => Ok(ProfileKind::Dev),
|
||||
_ => anyhow::bail!("Conflicting usage of --profile and --debug"),
|
||||
Some(name) if name != "dev" => {
|
||||
anyhow::bail!("Conflicting usage of --profile and --debug")
|
||||
}
|
||||
_ => Ok(InternedString::new("dev")),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Ok(specified_profile.unwrap_or(default))
|
||||
Ok(specified_profile.unwrap_or_else(|| InternedString::new(default)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,8 +436,7 @@ pub trait ArgMatchesExt {
|
||||
|
||||
let mut build_config = BuildConfig::new(config, self.jobs()?, &self.target(), mode)?;
|
||||
build_config.message_format = message_format.unwrap_or(MessageFormat::Human);
|
||||
build_config.profile_kind =
|
||||
self.get_profile_kind(config, ProfileKind::Dev, profile_checking)?;
|
||||
build_config.requested_profile = self.get_profile_name(config, "dev", profile_checking)?;
|
||||
build_config.build_plan = self._is_present("build-plan");
|
||||
if build_config.build_plan {
|
||||
config
|
||||
|
@ -425,13 +425,11 @@ impl<'config> ValueDeserializer<'config> {
|
||||
cv.definition().clone()
|
||||
}
|
||||
}
|
||||
(true, None) => env_def,
|
||||
(false, Some(cv)) => cv.definition().clone(),
|
||||
(false, None) => {
|
||||
return Err(
|
||||
anyhow::format_err!("failed to find definition of `{}`", de.key).into(),
|
||||
)
|
||||
}
|
||||
// Assume it is an environment, even if the key is not set.
|
||||
// This can happen for intermediate tables, like
|
||||
// CARGO_FOO_BAR_* where `CARGO_FOO_BAR` is not set.
|
||||
(_, None) => env_def,
|
||||
}
|
||||
};
|
||||
Ok(ValueDeserializer {
|
||||
|
@ -70,7 +70,6 @@ use serde::Deserialize;
|
||||
use url::Url;
|
||||
|
||||
use self::ConfigValue as CV;
|
||||
use crate::core::profiles::ConfigProfiles;
|
||||
use crate::core::shell::Verbosity;
|
||||
use crate::core::{nightly_features_allowed, CliUnstable, Shell, SourceId, Workspace};
|
||||
use crate::ops;
|
||||
@ -163,8 +162,6 @@ pub struct Config {
|
||||
target_dir: Option<Filesystem>,
|
||||
/// Environment variables, separated to assist testing.
|
||||
env: HashMap<String, String>,
|
||||
/// Profiles loaded from config.
|
||||
profiles: LazyCell<ConfigProfiles>,
|
||||
/// Tracks which sources have been updated to avoid multiple updates.
|
||||
updated_sources: LazyCell<RefCell<HashSet<SourceId>>>,
|
||||
/// Lock, if held, of the global package cache along with the number of
|
||||
@ -238,7 +235,6 @@ impl Config {
|
||||
creation_time: Instant::now(),
|
||||
target_dir: None,
|
||||
env,
|
||||
profiles: LazyCell::new(),
|
||||
updated_sources: LazyCell::new(),
|
||||
package_cache_lock: RefCell::new(None),
|
||||
http_config: LazyCell::new(),
|
||||
@ -372,26 +368,6 @@ impl Config {
|
||||
.map(AsRef::as_ref)
|
||||
}
|
||||
|
||||
/// Gets profiles defined in config files.
|
||||
pub fn profiles(&self) -> CargoResult<&ConfigProfiles> {
|
||||
self.profiles.try_borrow_with(|| {
|
||||
let ocp = self.get::<Option<ConfigProfiles>>("profile")?;
|
||||
if let Some(config_profiles) = ocp {
|
||||
// Warn if config profiles without CLI option.
|
||||
if !self.cli_unstable().config_profile {
|
||||
self.shell().warn(
|
||||
"profiles in config files require `-Z config-profile` \
|
||||
command-line option",
|
||||
)?;
|
||||
return Ok(ConfigProfiles::default());
|
||||
}
|
||||
Ok(config_profiles)
|
||||
} else {
|
||||
Ok(ConfigProfiles::default())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Which package sources have been updated, used to ensure it is only done once.
|
||||
pub fn updated_sources(&self) -> RefMut<'_, HashSet<SourceId>> {
|
||||
self.updated_sources
|
||||
|
@ -16,7 +16,6 @@ use url::Url;
|
||||
|
||||
use crate::core::dependency::DepKind;
|
||||
use crate::core::manifest::{LibKind, ManifestMetadata, TargetSourcePath, Warnings};
|
||||
use crate::core::profiles::Profiles;
|
||||
use crate::core::{Dependency, InternedString, Manifest, PackageId, Summary, Target};
|
||||
use crate::core::{Edition, EitherManifest, Feature, Features, VirtualManifest};
|
||||
use crate::core::{GitReference, PackageIdSpec, SourceId, WorkspaceConfig, WorkspaceRootConfig};
|
||||
@ -270,23 +269,19 @@ pub struct TomlManifest {
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Clone, Debug, Default)]
|
||||
pub struct TomlProfiles(BTreeMap<String, TomlProfile>);
|
||||
pub struct TomlProfiles(BTreeMap<InternedString, TomlProfile>);
|
||||
|
||||
impl TomlProfiles {
|
||||
pub fn get_all(&self) -> &BTreeMap<String, TomlProfile> {
|
||||
pub fn get_all(&self) -> &BTreeMap<InternedString, TomlProfile> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn get(&self, name: &'static str) -> Option<&TomlProfile> {
|
||||
self.0.get(&String::from(name))
|
||||
pub fn get(&self, name: &str) -> Option<&TomlProfile> {
|
||||
self.0.get(name)
|
||||
}
|
||||
|
||||
pub fn validate(&self, features: &Features, warnings: &mut Vec<String>) -> CargoResult<()> {
|
||||
for (name, profile) in &self.0 {
|
||||
if name == "debug" {
|
||||
warnings.push("use `[profile.dev]` to configure debug builds".to_string());
|
||||
}
|
||||
|
||||
profile.validate(name, features, warnings)?;
|
||||
}
|
||||
Ok(())
|
||||
@ -408,13 +403,10 @@ pub struct TomlProfile {
|
||||
pub panic: Option<String>,
|
||||
pub overflow_checks: Option<bool>,
|
||||
pub incremental: Option<bool>,
|
||||
// `overrides` has been renamed to `package`, this should be removed when
|
||||
// stabilized.
|
||||
pub overrides: Option<BTreeMap<ProfilePackageSpec, TomlProfile>>,
|
||||
pub package: Option<BTreeMap<ProfilePackageSpec, TomlProfile>>,
|
||||
pub build_override: Option<Box<TomlProfile>>,
|
||||
pub dir_name: Option<String>,
|
||||
pub inherits: Option<String>,
|
||||
pub dir_name: Option<InternedString>,
|
||||
pub inherits: Option<InternedString>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
|
||||
@ -458,21 +450,14 @@ impl TomlProfile {
|
||||
features: &Features,
|
||||
warnings: &mut Vec<String>,
|
||||
) -> CargoResult<()> {
|
||||
if name == "debug" {
|
||||
warnings.push("use `[profile.dev]` to configure debug builds".to_string());
|
||||
}
|
||||
|
||||
if let Some(ref profile) = self.build_override {
|
||||
features.require(Feature::profile_overrides())?;
|
||||
profile.validate_override("build-override")?;
|
||||
}
|
||||
if let Some(ref override_map) = self.overrides {
|
||||
warnings.push(
|
||||
"profile key `overrides` has been renamed to `package`, \
|
||||
please update the manifest to the new key name"
|
||||
.to_string(),
|
||||
);
|
||||
features.require(Feature::profile_overrides())?;
|
||||
for profile in override_map.values() {
|
||||
profile.validate_override("package")?;
|
||||
}
|
||||
}
|
||||
if let Some(ref packages) = self.package {
|
||||
features.require(Feature::profile_overrides())?;
|
||||
for profile in packages.values() {
|
||||
@ -570,7 +555,7 @@ impl TomlProfile {
|
||||
}
|
||||
|
||||
fn validate_override(&self, which: &str) -> CargoResult<()> {
|
||||
if self.overrides.is_some() || self.package.is_some() {
|
||||
if self.package.is_some() {
|
||||
bail!("package-specific profiles cannot be nested");
|
||||
}
|
||||
if self.build_override.is_some() {
|
||||
@ -588,6 +573,7 @@ impl TomlProfile {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Overwrite self's values with the given profile.
|
||||
pub fn merge(&mut self, profile: &TomlProfile) {
|
||||
if let Some(v) = &profile.opt_level {
|
||||
self.opt_level = Some(v.clone());
|
||||
@ -625,16 +611,27 @@ impl TomlProfile {
|
||||
self.incremental = Some(v);
|
||||
}
|
||||
|
||||
if let Some(v) = &profile.overrides {
|
||||
self.overrides = Some(v.clone());
|
||||
if let Some(other_package) = &profile.package {
|
||||
match &mut self.package {
|
||||
Some(self_package) => {
|
||||
for (spec, other_pkg_profile) in other_package {
|
||||
match self_package.get_mut(spec) {
|
||||
Some(p) => p.merge(other_pkg_profile),
|
||||
None => {
|
||||
self_package.insert(spec.clone(), other_pkg_profile.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None => self.package = Some(other_package.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(v) = &profile.package {
|
||||
self.package = Some(v.clone());
|
||||
}
|
||||
|
||||
if let Some(v) = &profile.build_override {
|
||||
self.build_override = Some(v.clone());
|
||||
if let Some(other_bo) = &profile.build_override {
|
||||
match &mut self.build_override {
|
||||
Some(self_bo) => self_bo.merge(other_bo),
|
||||
None => self.build_override = Some(other_bo.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(v) = &profile.inherits {
|
||||
@ -1173,7 +1170,10 @@ impl TomlManifest {
|
||||
`[workspace]`, only one can be specified"
|
||||
),
|
||||
};
|
||||
let profiles = Profiles::new(me.profile.as_ref(), config, &features, &mut warnings)?;
|
||||
let profiles = me.profile.clone();
|
||||
if let Some(profiles) = &profiles {
|
||||
profiles.validate(&features, &mut warnings)?;
|
||||
}
|
||||
let publish = match project.publish {
|
||||
Some(VecStringOrBool::VecString(ref vecstring)) => Some(vecstring.clone()),
|
||||
Some(VecStringOrBool::Bool(false)) => Some(vec![]),
|
||||
@ -1321,7 +1321,10 @@ impl TomlManifest {
|
||||
};
|
||||
(me.replace(&mut cx)?, me.patch(&mut cx)?)
|
||||
};
|
||||
let profiles = Profiles::new(me.profile.as_ref(), config, &features, &mut warnings)?;
|
||||
let profiles = me.profile.clone();
|
||||
if let Some(profiles) = &profiles {
|
||||
profiles.validate(&features, &mut warnings)?;
|
||||
}
|
||||
let workspace_config = match me.workspace {
|
||||
Some(ref config) => WorkspaceConfig::Root(WorkspaceRootConfig::new(
|
||||
root,
|
||||
|
@ -1,5 +1,11 @@
|
||||
//! Tests for config settings.
|
||||
|
||||
use cargo::core::{enable_nightly_features, InternedString, Shell};
|
||||
use cargo::util::config::{self, Config, SslVersionConfig, StringList};
|
||||
use cargo::util::toml::{self, VecStringOrBool as VSOB};
|
||||
use cargo::CargoResult;
|
||||
use cargo_test_support::{normalized_lines_match, paths, project, t};
|
||||
use serde::Deserialize;
|
||||
use std::borrow::Borrow;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::fs;
|
||||
@ -7,13 +13,6 @@ use std::io;
|
||||
use std::os;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use cargo::core::{enable_nightly_features, Shell};
|
||||
use cargo::util::config::{self, Config, SslVersionConfig, StringList};
|
||||
use cargo::util::toml::{self, VecStringOrBool as VSOB};
|
||||
use cargo::CargoResult;
|
||||
use cargo_test_support::{normalized_lines_match, paths, project, t};
|
||||
use serde::Deserialize;
|
||||
|
||||
/// Helper for constructing a `Config` object.
|
||||
pub struct ConfigBuilder {
|
||||
env: HashMap<String, String>,
|
||||
@ -424,8 +423,8 @@ lto = false
|
||||
p,
|
||||
toml::TomlProfile {
|
||||
lto: Some(toml::StringOrBool::Bool(false)),
|
||||
dir_name: Some("without-lto".to_string()),
|
||||
inherits: Some("dev".to_string()),
|
||||
dir_name: Some(InternedString::new("without-lto")),
|
||||
inherits: Some(InternedString::new("dev")),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! Tests for profiles defined in config files.
|
||||
|
||||
use cargo_test_support::paths::CargoPathExt;
|
||||
use cargo_test_support::{basic_lib_manifest, paths, project};
|
||||
|
||||
#[cargo_test]
|
||||
@ -19,13 +20,44 @@ fn profile_config_gated() {
|
||||
p.cargo("build -v")
|
||||
.with_stderr_contains(
|
||||
"\
|
||||
[WARNING] profiles in config files require `-Z config-profile` command-line option
|
||||
[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.
|
||||
let p = project()
|
||||
.file("src/lib.rs", "")
|
||||
.file(
|
||||
".cargo/config",
|
||||
r#"
|
||||
[profile.foo]
|
||||
inherits = 'dev'
|
||||
opt-level = 1
|
||||
"#,
|
||||
)
|
||||
.build();
|
||||
p.cargo("build --profile foo -Zunstable-options -Zconfig-profile")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] config profile `foo` is not valid (defined in `[..]/foo/.cargo/config`)
|
||||
|
||||
Caused by:
|
||||
feature `named-profiles` is required
|
||||
|
||||
consider adding `cargo-features = [\"named-profiles\"]` to the manifest
|
||||
",
|
||||
)
|
||||
.with_status(101)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn profile_config_validate_warnings() {
|
||||
let p = project()
|
||||
@ -56,8 +88,6 @@ fn profile_config_validate_warnings() {
|
||||
.masquerade_as_nightly_cargo()
|
||||
.with_stderr_unordered(
|
||||
"\
|
||||
[WARNING] unused config key `profile.asdf` in `[..].cargo/config`
|
||||
[WARNING] unused config key `profile.test` in `[..].cargo/config`
|
||||
[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`
|
||||
@ -70,6 +100,7 @@ fn profile_config_validate_warnings() {
|
||||
|
||||
#[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", "")
|
||||
@ -94,10 +125,10 @@ fn profile_config_error_paths() {
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`
|
||||
|
||||
Caused by:
|
||||
error in [..].cargo/config: `profile.dev.rpath` expected true/false, but found a string
|
||||
[ERROR] error in [..]/foo/.cargo/config: \
|
||||
could not load config key `profile.dev`: \
|
||||
error in [..]/home/.cargo/config: \
|
||||
`profile.dev.rpath` expected true/false, but found a string
|
||||
",
|
||||
)
|
||||
.run();
|
||||
@ -122,7 +153,7 @@ fn profile_config_validate_errors() {
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] config profile `profile.dev` is not valid
|
||||
[ERROR] config profile `dev` is not valid (defined in `[..]/foo/.cargo/config`)
|
||||
|
||||
Caused by:
|
||||
`panic` may not be specified in a `package` profile
|
||||
@ -150,10 +181,10 @@ fn profile_config_syntax_errors() {
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at [..]
|
||||
|
||||
Caused by:
|
||||
error in [..].cargo/config: `profile.dev.codegen-units` expected an integer, but found a string
|
||||
[ERROR] error in [..]/foo/.cargo/config: \
|
||||
could not load config key `profile.dev`: \
|
||||
error in [..]/foo/.cargo/config: \
|
||||
`profile.dev.codegen-units` expected an integer, but found a string
|
||||
",
|
||||
)
|
||||
.run();
|
||||
@ -337,3 +368,123 @@ fn profile_config_mixed_types() {
|
||||
.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::CompileMode;
|
||||
use cargo::core::enable_nightly_features;
|
||||
use cargo::core::features::Features;
|
||||
use cargo::core::profiles::{Profiles, UnitFor};
|
||||
use cargo::core::{InternedString, PackageId};
|
||||
use cargo::util::toml::TomlProfiles;
|
||||
use std::fs;
|
||||
enable_nightly_features();
|
||||
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();
|
||||
let config = ConfigBuilder::new().unstable_flag("config-profile").build();
|
||||
let mut warnings = Vec::new();
|
||||
let features = Features::new(&["named-profiles".to_string()], &mut warnings).unwrap();
|
||||
assert_eq!(warnings.len(), 0);
|
||||
let profile_name = InternedString::new("foo");
|
||||
let toml = r#"
|
||||
[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
|
||||
"#;
|
||||
#[derive(serde::Deserialize)]
|
||||
struct TomlManifest {
|
||||
profile: Option<TomlProfiles>,
|
||||
}
|
||||
let manifest: TomlManifest = toml::from_str(toml).unwrap();
|
||||
let profiles =
|
||||
Profiles::new(manifest.profile.as_ref(), &config, profile_name, &features).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 p = profiles.get_profile(a_pkg, true, UnitFor::new_normal(), CompileMode::Build);
|
||||
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, Some(1)); // "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, UnitFor::new_build(), CompileMode::Build);
|
||||
assert_eq!(bo.name, "foo");
|
||||
assert_eq!(bo.codegen_units, Some(6)); // "foo" build override from config
|
||||
assert_eq!(bo.opt_level, "1"); // SAME as normal
|
||||
assert_eq!(bo.debuginfo, Some(1)); // 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, UnitFor::new_normal(), CompileMode::Build);
|
||||
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, Some(1)); // 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#"
|
||||
cargo-features = ["named-profiles"]
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.1.0"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("build -v -Zconfig-profile -Zunstable-options --profile=other")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.env("CARGO_PROFILE_OTHER_CODEGEN_UNITS", "1")
|
||||
.env("CARGO_PROFILE_OTHER_INHERITS", "dev")
|
||||
.with_stderr_contains("[..]-C codegen-units=1 [..]")
|
||||
.run();
|
||||
}
|
||||
|
@ -27,10 +27,7 @@ fn inherits_on_release() {
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at [..]
|
||||
|
||||
Caused by:
|
||||
An 'inherits' must not specified root profile 'release'
|
||||
[ERROR] `inherits` must not be specified in root profile `release`
|
||||
",
|
||||
)
|
||||
.run();
|
||||
@ -61,10 +58,9 @@ fn missing_inherits() {
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at [..]
|
||||
|
||||
Caused by:
|
||||
An 'inherits' directive is needed for all profiles that are not 'dev' or 'release'. Here it is missing from 'release-lto'",
|
||||
[ERROR] profile `release-lto` is missing an `inherits` directive \
|
||||
(`inherits` is required for all profiles except `dev` or `release`)
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
@ -198,10 +194,8 @@ fn non_existent_inherits() {
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at [..]
|
||||
|
||||
Caused by:
|
||||
Profile 'non-existent' not found in Cargo.toml",
|
||||
[ERROR] profile `release-lto` inherits from `non-existent`, but that profile is not defined
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
@ -232,10 +226,8 @@ fn self_inherits() {
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at [..]
|
||||
|
||||
Caused by:
|
||||
Inheritance loop of profiles cycles with profile 'release-lto'",
|
||||
[ERROR] profile inheritance loop detected with profile `release-lto` inheriting `release-lto`
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
@ -270,10 +262,8 @@ fn inherits_loop() {
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at [..]
|
||||
|
||||
Caused by:
|
||||
Inheritance loop of profiles cycles with profile 'release-lto'",
|
||||
[ERROR] profile inheritance loop detected with profile `release-lto2` inheriting `release-lto`
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
@ -477,3 +467,32 @@ fn clean_custom_dirname() {
|
||||
assert!(p.build_dir().join("debug").is_dir());
|
||||
assert!(!p.build_dir().join("other").is_dir());
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn unknown_profile() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["named-profiles"]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("build --profile alpha -Zunstable-options")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.with_stderr("[ERROR] profile `alpha` is not defined")
|
||||
.with_status(101)
|
||||
.run();
|
||||
// Clean has a separate code path, need to check it too.
|
||||
p.cargo("clean --profile alpha -Zunstable-options")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.with_stderr("[ERROR] profile `alpha` is not defined")
|
||||
.with_status(101)
|
||||
.run();
|
||||
}
|
||||
|
@ -68,13 +68,16 @@ fn profile_override_warnings() {
|
||||
.file("bar/src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("build").with_stderr_contains(
|
||||
p.cargo("build")
|
||||
.with_stderr_contains(
|
||||
"\
|
||||
[WARNING] version or URL in package profile spec `bar:1.2.3` does not match any of the packages: bar v0.5.0 ([..])
|
||||
[WARNING] package profile spec `bart` did not match any packages
|
||||
[WARNING] profile package spec `bar:1.2.3` in profile `dev` \
|
||||
has a version or URL that does not match any of the packages: \
|
||||
bar v0.5.0 ([..]/foo/bar)
|
||||
[WARNING] profile package spec `bart` in profile `dev` did not match any packages
|
||||
|
||||
<tab>Did you mean `bar`?
|
||||
[WARNING] package profile spec `no-suggestion` did not match any packages
|
||||
[WARNING] profile package spec `no-suggestion` in profile `dev` did not match any packages
|
||||
[COMPILING] [..]
|
||||
",
|
||||
)
|
||||
@ -96,10 +99,7 @@ fn profile_override_bad_settings() {
|
||||
"rpath = true",
|
||||
"`rpath` may not be specified in a `package` profile",
|
||||
),
|
||||
(
|
||||
"overrides = {}",
|
||||
"package-specific profiles cannot be nested",
|
||||
),
|
||||
("package = {}", "package-specific profiles cannot be nested"),
|
||||
];
|
||||
for &(snippet, expected) in bad_values.iter() {
|
||||
let p = project()
|
||||
@ -394,42 +394,6 @@ fn override_proc_macro() {
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn override_package_rename() {
|
||||
// backwards-compatibility test
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
bar = {path = "bar"}
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
|
||||
[profile.dev.overrides.bar]
|
||||
opt-level = 3
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.file("bar/Cargo.toml", &basic_lib_manifest("bar"))
|
||||
.file("bar/src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("check")
|
||||
.with_stderr("\
|
||||
[WARNING] profile key `overrides` has been renamed to `package`, please update the manifest to the new key name
|
||||
[CHECKING] bar [..]
|
||||
[CHECKING] foo [..]
|
||||
[FINISHED] [..]
|
||||
")
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn no_warning_ws() {
|
||||
// https://github.com/rust-lang/cargo/issues/7378, avoid warnings in a workspace.
|
||||
|
Loading…
x
Reference in New Issue
Block a user