mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Consolidate build
key configuration
Add a typed structure which lists all `build` key configuration throughout Cargo.
This commit is contained in:
parent
09d9165d27
commit
d7d8ca1e12
@ -62,15 +62,16 @@ impl BuildConfig {
|
||||
requested_target: &Option<String>,
|
||||
mode: CompileMode,
|
||||
) -> CargoResult<BuildConfig> {
|
||||
let cfg = config.build_config()?;
|
||||
let requested_kind = match requested_target {
|
||||
Some(s) => CompileKind::Target(CompileTarget::new(s)?),
|
||||
None => match config.get_string("build.target")? {
|
||||
Some(cfg) => {
|
||||
let value = if cfg.val.ends_with(".json") {
|
||||
let path = cfg.definition.root(config).join(&cfg.val);
|
||||
None => match &cfg.target {
|
||||
Some(val) => {
|
||||
let value = if val.raw_value().ends_with(".json") {
|
||||
let path = val.clone().resolve_path(config);
|
||||
path.to_str().expect("must be utf-8 in toml").to_string()
|
||||
} else {
|
||||
cfg.val
|
||||
val.raw_value().to_string()
|
||||
};
|
||||
CompileKind::Target(CompileTarget::new(&value)?)
|
||||
}
|
||||
@ -88,8 +89,7 @@ impl BuildConfig {
|
||||
its environment, ignoring the `-j` parameter",
|
||||
)?;
|
||||
}
|
||||
let cfg_jobs: Option<u32> = config.get("build.jobs")?;
|
||||
let jobs = jobs.or(cfg_jobs).unwrap_or(::num_cpus::get() as u32);
|
||||
let jobs = jobs.or(cfg.jobs).unwrap_or(::num_cpus::get() as u32);
|
||||
|
||||
Ok(BuildConfig {
|
||||
requested_kind,
|
||||
|
@ -7,6 +7,7 @@ use std::str::{self, FromStr};
|
||||
use crate::core::compiler::CompileKind;
|
||||
use crate::core::TargetKind;
|
||||
use crate::util::{CargoResult, CargoResultExt, Config, ProcessBuilder, Rustc};
|
||||
use crate::util::config::StringList;
|
||||
use cargo_platform::{Cfg, CfgExpr};
|
||||
|
||||
/// Information about the platform target gleaned from querying rustc.
|
||||
@ -427,9 +428,8 @@ fn env_args(
|
||||
CompileKind::Target(target) => target.short_name(),
|
||||
};
|
||||
let key = format!("target.{}.{}", target, name);
|
||||
if let Some(args) = config.get_list_or_split_string(&key)? {
|
||||
let args = args.val.into_iter();
|
||||
rustflags.extend(args);
|
||||
if let Some(args) = config.get::<Option<StringList>>(&key)? {
|
||||
rustflags.extend(args.as_slice().iter().cloned());
|
||||
}
|
||||
// ...including target.'cfg(...)'.rustflags
|
||||
if let Some(target_cfg) = target_cfg {
|
||||
@ -450,9 +450,8 @@ fn env_args(
|
||||
|
||||
for n in cfgs {
|
||||
let key = format!("target.{}.{}", n, name);
|
||||
if let Some(args) = config.get_list_or_split_string(&key)? {
|
||||
let args = args.val.into_iter();
|
||||
rustflags.extend(args);
|
||||
if let Some(args) = config.get::<Option<StringList>>(&key)? {
|
||||
rustflags.extend(args.as_slice().iter().cloned());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -463,10 +462,14 @@ fn env_args(
|
||||
}
|
||||
|
||||
// Then the `build.rustflags` value.
|
||||
let key = format!("build.{}", name);
|
||||
if let Some(args) = config.get_list_or_split_string(&key)? {
|
||||
let args = args.val.into_iter();
|
||||
return Ok(args.collect());
|
||||
let build = config.build_config()?;
|
||||
let list = if name == "rustflags" {
|
||||
&build.rustflags
|
||||
} else {
|
||||
&build.rustdocflags
|
||||
};
|
||||
if let Some(list) = list {
|
||||
return Ok(list.as_slice().to_vec())
|
||||
}
|
||||
|
||||
Ok(Vec::new())
|
||||
|
@ -99,10 +99,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
|
||||
}
|
||||
};
|
||||
|
||||
let pipelining = bcx
|
||||
.config
|
||||
.get::<Option<bool>>("build.pipelining")?
|
||||
.unwrap_or(true);
|
||||
let pipelining = bcx.config.build_config()?.pipelining.unwrap_or(true);
|
||||
|
||||
Ok(Self {
|
||||
bcx,
|
||||
|
@ -81,10 +81,10 @@ pub fn output_depinfo<'a, 'b>(cx: &mut Context<'a, 'b>, unit: &Unit<'a>) -> Carg
|
||||
let mut visited = HashSet::new();
|
||||
let success = add_deps_for_unit(&mut deps, cx, unit, &mut visited).is_ok();
|
||||
let basedir_string;
|
||||
let basedir = match bcx.config.get_path("build.dep-info-basedir")? {
|
||||
let basedir = match bcx.config.build_config()?.dep_info_basedir.clone() {
|
||||
Some(value) => {
|
||||
basedir_string = value
|
||||
.val
|
||||
.resolve_path(bcx.config)
|
||||
.as_os_str()
|
||||
.to_str()
|
||||
.ok_or_else(|| internal("build.dep-info-basedir path not utf-8"))?
|
||||
|
@ -38,7 +38,7 @@ impl Profiles {
|
||||
|
||||
let incremental = match env::var_os("CARGO_INCREMENTAL") {
|
||||
Some(v) => Some(v == "1"),
|
||||
None => config.get::<Option<bool>>("build.incremental")?,
|
||||
None => config.build_config()?.incremental,
|
||||
};
|
||||
|
||||
if !features.is_enabled(Feature::named_profiles()) {
|
||||
|
@ -420,7 +420,7 @@ pub fn configure_http_handle(config: &Config, handle: &mut Easy) -> CargoResult<
|
||||
handle.proxy(&proxy)?;
|
||||
}
|
||||
if let Some(cainfo) = http.cainfo.clone() {
|
||||
let cainfo = cainfo.resolve(config);
|
||||
let cainfo = cainfo.resolve_path(config);
|
||||
handle.cainfo(&cainfo)?;
|
||||
}
|
||||
if let Some(check) = http.check_revoke {
|
||||
|
@ -97,6 +97,7 @@ pub struct Config {
|
||||
/// Cached configuration parsed by Cargo
|
||||
http_config: LazyCell<CargoHttpConfig>,
|
||||
net_config: LazyCell<CargoNetConfig>,
|
||||
build_config: LazyCell<CargoBuildConfig>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
@ -157,6 +158,7 @@ impl Config {
|
||||
package_cache_lock: RefCell::new(None),
|
||||
http_config: LazyCell::new(),
|
||||
net_config: LazyCell::new(),
|
||||
build_config: LazyCell::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -338,12 +340,12 @@ impl Config {
|
||||
}
|
||||
|
||||
pub fn target_dir(&self) -> CargoResult<Option<Filesystem>> {
|
||||
if let Some(ref dir) = self.target_dir {
|
||||
if let Some(dir) = &self.target_dir {
|
||||
Ok(Some(dir.clone()))
|
||||
} else if let Some(dir) = env::var_os("CARGO_TARGET_DIR") {
|
||||
Ok(Some(Filesystem::new(self.cwd.join(dir))))
|
||||
} else if let Some(val) = self.get_path("build.target-dir")? {
|
||||
let val = self.cwd.join(val.val);
|
||||
} else if let Some(val) = &self.build_config()?.target_dir {
|
||||
let val = val.resolve_path(self);
|
||||
Ok(Some(Filesystem::new(val)))
|
||||
} else {
|
||||
Ok(None)
|
||||
@ -469,7 +471,7 @@ impl Config {
|
||||
pub fn get_path(&self, key: &str) -> CargoResult<OptValue<PathBuf>> {
|
||||
self.get::<Option<Value<ConfigRelativePath>>>(key).map(|v| {
|
||||
v.map(|v| Value {
|
||||
val: v.val.resolve(self),
|
||||
val: v.val.resolve_program(self),
|
||||
definition: v.definition,
|
||||
})
|
||||
})
|
||||
@ -513,27 +515,13 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_list_or_split_string(&self, key: &str) -> CargoResult<OptValue<Vec<String>>> {
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum Target {
|
||||
String(String),
|
||||
List(Vec<String>),
|
||||
}
|
||||
|
||||
match self.get::<Option<Value<Target>>>(key)? {
|
||||
fn get_list_or_split_string(&self, key: &str) -> CargoResult<OptValue<Vec<String>>> {
|
||||
match self.get::<Option<Value<StringList>>>(key)? {
|
||||
None => Ok(None),
|
||||
Some(Value {
|
||||
val: Target::String(s),
|
||||
definition,
|
||||
}) => Ok(Some(Value {
|
||||
val: s.split(' ').map(str::to_string).collect(),
|
||||
definition,
|
||||
Some(val) => Ok(Some(Value {
|
||||
val: val.val.list,
|
||||
definition: val.definition,
|
||||
})),
|
||||
Some(Value {
|
||||
val: Target::List(val),
|
||||
definition,
|
||||
}) => Ok(Some(Value { val, definition })),
|
||||
}
|
||||
}
|
||||
|
||||
@ -927,6 +915,11 @@ impl Config {
|
||||
.try_borrow_with(|| Ok(self.get::<CargoNetConfig>("net")?))
|
||||
}
|
||||
|
||||
pub fn build_config(&self) -> CargoResult<&CargoBuildConfig> {
|
||||
self.build_config
|
||||
.try_borrow_with(|| Ok(self.get::<CargoBuildConfig>("build")?))
|
||||
}
|
||||
|
||||
pub fn crates_io_source_id<F>(&self, f: F) -> CargoResult<SourceId>
|
||||
where
|
||||
F: FnMut() -> CargoResult<SourceId>,
|
||||
@ -1463,3 +1456,46 @@ pub struct CargoNetConfig {
|
||||
#[serde(rename = "git-fetch-with-cli")]
|
||||
pub git_fetch_with_cli: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct CargoBuildConfig {
|
||||
pub pipelining: Option<bool>,
|
||||
#[serde(rename = "dep-info-basedir")]
|
||||
pub dep_info_basedir: Option<ConfigRelativePath>,
|
||||
#[serde(rename = "target-dir")]
|
||||
pub target_dir: Option<ConfigRelativePath>,
|
||||
pub incremental: Option<bool>,
|
||||
pub target: Option<ConfigRelativePath>,
|
||||
pub jobs: Option<u32>,
|
||||
pub rustflags: Option<StringList>,
|
||||
pub rustdocflags: Option<StringList>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct StringList {
|
||||
list: Vec<String>,
|
||||
}
|
||||
|
||||
impl StringList {
|
||||
pub fn as_slice(&self) -> &[String] {
|
||||
&self.list
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::de::Deserialize<'de> for StringList {
|
||||
fn deserialize<D: serde::de::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum Target {
|
||||
String(String),
|
||||
List(Vec<String>),
|
||||
}
|
||||
|
||||
Ok(match Target::deserialize(d)? {
|
||||
Target::String(s) => StringList {
|
||||
list: s.split_whitespace().map(str::to_string).collect(),
|
||||
},
|
||||
Target::List(list) => StringList { list },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,26 @@ use std::path::PathBuf;
|
||||
pub struct ConfigRelativePath(Value<String>);
|
||||
|
||||
impl ConfigRelativePath {
|
||||
pub fn resolve(self, config: &Config) -> PathBuf {
|
||||
/// Returns the raw underlying configuration value for this key.
|
||||
pub fn raw_value(&self) -> &str {
|
||||
&self.0.val
|
||||
}
|
||||
|
||||
/// Resolves this configuration-relative path to an absolute path.
|
||||
///
|
||||
/// This will always return an absolute path where it's relative to the
|
||||
/// location for configuration for this value.
|
||||
pub fn resolve_path(&self, config: &Config) -> PathBuf {
|
||||
self.0.definition.root(config).join(&self.0.val)
|
||||
}
|
||||
|
||||
/// Resolves this configuration-relative path to either an absolute path or
|
||||
/// something appropriate to execute from `PATH`.
|
||||
///
|
||||
/// Values which don't look like a filesystem path (don't contain `/` or
|
||||
/// `\`) will be returned as-is, and everything else will fall through to an
|
||||
/// absolute path.
|
||||
pub fn resolve_program(self, config: &Config) -> PathBuf {
|
||||
config.string_to_path(self.0.val, &self.0.definition)
|
||||
}
|
||||
}
|
||||
|
@ -394,5 +394,5 @@ pub fn display_causes(error: &Error) -> String {
|
||||
.iter_chain()
|
||||
.map(|e| e.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\nCaused by:\n ")
|
||||
.join("\n\nCaused by:\n ")
|
||||
}
|
||||
|
@ -560,10 +560,13 @@ fn config_bad_toml() {
|
||||
config.get::<i32>("foo").unwrap_err(),
|
||||
"\
|
||||
could not load Cargo configuration
|
||||
|
||||
Caused by:
|
||||
could not parse TOML configuration in `[..]/.cargo/config`
|
||||
|
||||
Caused by:
|
||||
could not parse input as TOML
|
||||
|
||||
Caused by:
|
||||
expected an equals, found eof at line 1 column 5",
|
||||
);
|
||||
@ -735,35 +738,35 @@ abs = '{}'
|
||||
config
|
||||
.get::<config::ConfigRelativePath>("p1")
|
||||
.unwrap()
|
||||
.resolve(&config),
|
||||
.resolve_path(&config),
|
||||
paths::root().join("foo/bar")
|
||||
);
|
||||
assert_eq!(
|
||||
config
|
||||
.get::<config::ConfigRelativePath>("p2")
|
||||
.unwrap()
|
||||
.resolve(&config),
|
||||
.resolve_path(&config),
|
||||
paths::root().join("../abc")
|
||||
);
|
||||
assert_eq!(
|
||||
config
|
||||
.get::<config::ConfigRelativePath>("p3")
|
||||
.unwrap()
|
||||
.resolve(&config),
|
||||
.resolve_path(&config),
|
||||
paths::root().join("d/e")
|
||||
);
|
||||
assert_eq!(
|
||||
config
|
||||
.get::<config::ConfigRelativePath>("abs")
|
||||
.unwrap()
|
||||
.resolve(&config),
|
||||
.resolve_path(&config),
|
||||
paths::home()
|
||||
);
|
||||
assert_eq!(
|
||||
config
|
||||
.get::<config::ConfigRelativePath>("epath")
|
||||
.unwrap()
|
||||
.resolve(&config),
|
||||
.resolve_path(&config),
|
||||
paths::root().join("a/b")
|
||||
);
|
||||
}
|
||||
|
@ -1061,8 +1061,10 @@ fn new_warning_with_corrupt_ws() {
|
||||
[WARNING] compiling this new crate may not work due to invalid workspace configuration
|
||||
|
||||
failed to parse manifest at `[..]foo/Cargo.toml`
|
||||
|
||||
Caused by:
|
||||
could not parse input as TOML
|
||||
|
||||
Caused by:
|
||||
expected an equals, found eof at line 1 column 5
|
||||
Created binary (application) `bar` package
|
||||
|
Loading…
x
Reference in New Issue
Block a user