feat: add support for replacement flags in build specifications and enhance flag processing
This commit is contained in:
+126
-4
@@ -62,6 +62,61 @@ fn configured_install_dir(value: &str, default: &str) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
fn split_replacement_spec<'a>(current: &[String], spec: &'a str) -> Option<(&'a str, &'a str)> {
|
||||
let trimmed = spec.trim();
|
||||
if trimmed.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some((from, to)) = trimmed.split_once("=>") {
|
||||
return (!from.is_empty() && !to.is_empty()).then_some((from, to));
|
||||
}
|
||||
|
||||
let eq_positions: Vec<usize> = trimmed.match_indices('=').map(|(idx, _)| idx).collect();
|
||||
if eq_positions.is_empty() {
|
||||
return None;
|
||||
}
|
||||
if eq_positions.len() == 1 {
|
||||
let (from, to) = trimmed.split_once('=')?;
|
||||
return (!from.is_empty() && !to.is_empty()).then_some((from, to));
|
||||
}
|
||||
|
||||
eq_positions
|
||||
.into_iter()
|
||||
.filter_map(|idx| {
|
||||
let from = &trimmed[..idx];
|
||||
let to = &trimmed[idx + 1..];
|
||||
(!from.is_empty() && !to.is_empty() && current.iter().any(|flag| flag.contains(from)))
|
||||
.then_some((from, to))
|
||||
})
|
||||
.max_by_key(|(from, _)| from.len())
|
||||
}
|
||||
|
||||
fn apply_replacement_rules(current: &mut [String], replacements: &[String], label: &str) {
|
||||
for spec in replacements {
|
||||
let Some((from, to)) = split_replacement_spec(current, spec) else {
|
||||
if !spec.trim().is_empty() && !current.is_empty() {
|
||||
crate::log_warn!(
|
||||
"Skipping invalid {} entry '{}'; expected 'old=>new' or an unambiguous 'old=new'",
|
||||
label,
|
||||
spec
|
||||
);
|
||||
}
|
||||
continue;
|
||||
};
|
||||
|
||||
for flag in current.iter_mut() {
|
||||
*flag = flag.replace(from, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn replaced_flags(values: &[String], replacements: &[String], label: &str) -> Vec<String> {
|
||||
let mut current = values.to_vec();
|
||||
apply_replacement_rules(&mut current, replacements, label);
|
||||
current
|
||||
}
|
||||
|
||||
pub(crate) fn install_dirs(flags: &crate::package::BuildFlags) -> InstallDirs {
|
||||
let libdir = configured_install_dir(
|
||||
&flags.libdir,
|
||||
@@ -90,10 +145,26 @@ pub(crate) fn install_dirs(flags: &crate::package::BuildFlags) -> InstallDirs {
|
||||
fn compiler_flag_sets(
|
||||
flags: &crate::package::BuildFlags,
|
||||
) -> (Vec<String>, Vec<String>, Vec<String>, Vec<String>) {
|
||||
let mut cflags = flags.cflags.clone();
|
||||
let mut cxxflags = flags.cxxflags.clone();
|
||||
let mut ldflags = flags.ldflags.clone();
|
||||
let ltoflags = flags.ltoflags.clone();
|
||||
let mut cflags = replaced_flags(
|
||||
&flags.cflags,
|
||||
&flags.replace_cflags,
|
||||
"build.flags.replace_cflags",
|
||||
);
|
||||
let mut cxxflags = replaced_flags(
|
||||
&flags.cxxflags,
|
||||
&flags.replace_cxxflags,
|
||||
"build.flags.replace_cxxflags",
|
||||
);
|
||||
let mut ldflags = replaced_flags(
|
||||
&flags.ldflags,
|
||||
&flags.replace_ldflags,
|
||||
"build.flags.replace_ldflags",
|
||||
);
|
||||
let ltoflags = replaced_flags(
|
||||
&flags.ltoflags,
|
||||
&flags.replace_ltoflags,
|
||||
"build.flags.replace_ltoflags",
|
||||
);
|
||||
|
||||
if flags.use_lto && !ltoflags.is_empty() {
|
||||
cflags.extend(ltoflags.iter().cloned());
|
||||
@@ -104,6 +175,14 @@ fn compiler_flag_sets(
|
||||
(cflags, cxxflags, ldflags, ltoflags)
|
||||
}
|
||||
|
||||
pub(crate) fn effective_rustflags(flags: &crate::package::BuildFlags) -> Vec<String> {
|
||||
replaced_flags(
|
||||
&flags.rustflags,
|
||||
&flags.replace_rustflags,
|
||||
"build.flags.replace_rustflags",
|
||||
)
|
||||
}
|
||||
|
||||
pub fn standard_build_env(
|
||||
spec: &PackageSpec,
|
||||
cross: Option<&CrossConfig>,
|
||||
@@ -550,6 +629,40 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_standard_build_env_applies_replace_flag_rules() {
|
||||
let mut spec = mk_spec(vec!["-D_FORTIFY_SOURCE=3", "-O2"], vec!["-Wl,-O3"]);
|
||||
spec.build.flags.cxxflags = vec!["-O2".into(), "-stdlib=libc++".into()];
|
||||
spec.build.flags.replace_cflags = vec!["_FORTIFY_SOURCE=3=_FORTIFY_SOURCE=2".into()];
|
||||
spec.build.flags.replace_cxxflags = vec!["-stdlib=libc++=>-stdlib=libstdc++".into()];
|
||||
spec.build.flags.replace_ldflags = vec!["-O3=>-O2".into()];
|
||||
spec.build.flags.ltoflags = vec!["-flto=auto".into()];
|
||||
spec.build.flags.replace_ltoflags = vec!["auto=>thin".into()];
|
||||
spec.build.flags.use_lto = true;
|
||||
|
||||
let env = standard_build_env(&spec, None, true, true);
|
||||
assert!(
|
||||
env.iter()
|
||||
.any(|(k, v)| k == "CFLAGS" && v == "-D_FORTIFY_SOURCE=2 -O2 -flto=thin"),
|
||||
"expected replace_cflags and replace_ltoflags to be applied"
|
||||
);
|
||||
assert!(
|
||||
env.iter()
|
||||
.any(|(k, v)| { k == "CXXFLAGS" && v == "-O2 -stdlib=libstdc++ -flto=thin" }),
|
||||
"expected replace_cxxflags to be applied"
|
||||
);
|
||||
assert!(
|
||||
env.iter()
|
||||
.any(|(k, v)| k == "LDFLAGS" && v == "-Wl,-O2 -flto=thin"),
|
||||
"expected replace_ldflags to be applied"
|
||||
);
|
||||
assert!(
|
||||
env.iter()
|
||||
.any(|(k, v)| k == "LTOFLAGS" && v == "-flto=thin"),
|
||||
"expected replace_ltoflags to affect exported LTOFLAGS"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_standard_build_env_skips_lto_injection_when_disabled() {
|
||||
let mut spec = mk_spec(vec!["-O2"], vec!["-Wl,--as-needed"]);
|
||||
@@ -607,6 +720,15 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_effective_rustflags_applies_replace_rules() {
|
||||
let mut flags = BuildFlags::default();
|
||||
flags.rustflags = vec!["-C".into(), "debuginfo=2".into()];
|
||||
flags.replace_rustflags = vec!["debuginfo=2=>opt-level=2".into()];
|
||||
|
||||
assert_eq!(effective_rustflags(&flags), vec!["-C", "opt-level=2"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_standard_build_env_passthrough_does_not_override_default_vars() {
|
||||
let mut spec = mk_spec(Vec::new(), Vec::new());
|
||||
|
||||
+3
-2
@@ -50,8 +50,9 @@ pub fn build(
|
||||
crate::builder::standard_build_env(spec, cross, false, export_compiler_flags);
|
||||
|
||||
// RUSTFLAGS
|
||||
if !flags.rustflags.is_empty() {
|
||||
crate::builder::set_env_var(&mut env_vars, "RUSTFLAGS", flags.rustflags.join(" "));
|
||||
let rustflags = crate::builder::effective_rustflags(flags);
|
||||
if !rustflags.is_empty() {
|
||||
crate::builder::set_env_var(&mut env_vars, "RUSTFLAGS", rustflags.join(" "));
|
||||
}
|
||||
|
||||
// If cross-compiling, set linker via CARGO_TARGET_*_LINKER
|
||||
|
||||
@@ -719,9 +719,19 @@ fn make_lib32_build_spec(base: &package::PackageSpec) -> package::PackageSpec {
|
||||
if !flags.cflags_lib32.is_empty() {
|
||||
flags.cflags.extend(flags.cflags_lib32.clone());
|
||||
}
|
||||
if !flags.replace_cflags_lib32.is_empty() {
|
||||
flags
|
||||
.replace_cflags
|
||||
.extend(flags.replace_cflags_lib32.clone());
|
||||
}
|
||||
if !flags.cxxflags_lib32.is_empty() {
|
||||
flags.cxxflags.extend(flags.cxxflags_lib32.clone());
|
||||
}
|
||||
if !flags.replace_cxxflags_lib32.is_empty() {
|
||||
flags
|
||||
.replace_cxxflags
|
||||
.extend(flags.replace_cxxflags_lib32.clone());
|
||||
}
|
||||
if !flags.configure_lib32.is_empty() {
|
||||
flags.configure = flags.configure_lib32.clone();
|
||||
}
|
||||
@@ -5901,4 +5911,31 @@ optional = []
|
||||
"/tmp/depot-test-rootfs"
|
||||
)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn make_lib32_build_spec_merges_replace_flag_rules() {
|
||||
let mut base = test_package_spec(package::BuildType::Custom, None, &[]);
|
||||
base.build.flags.cflags = vec!["-O2".into()];
|
||||
base.build.flags.replace_cflags = vec!["-O2=>-O3".into()];
|
||||
base.build.flags.cflags_lib32 = vec!["-m32".into()];
|
||||
base.build.flags.replace_cflags_lib32 = vec!["-m32=>-mstackrealign".into()];
|
||||
base.build.flags.cxxflags = vec!["-O2".into()];
|
||||
base.build.flags.replace_cxxflags = vec!["-O2=>-O3".into()];
|
||||
base.build.flags.cxxflags_lib32 = vec!["-fno-rtti".into()];
|
||||
base.build.flags.replace_cxxflags_lib32 = vec!["-fno-rtti=>-fno-exceptions".into()];
|
||||
|
||||
let lib32 = make_lib32_build_spec(&base);
|
||||
|
||||
assert!(lib32.build.flags.lib32_variant);
|
||||
assert_eq!(lib32.build.flags.cflags, vec!["-O2", "-m32"]);
|
||||
assert_eq!(
|
||||
lib32.build.flags.replace_cflags,
|
||||
vec!["-O2=>-O3", "-m32=>-mstackrealign"]
|
||||
);
|
||||
assert_eq!(lib32.build.flags.cxxflags, vec!["-O2", "-fno-rtti"]);
|
||||
assert_eq!(
|
||||
lib32.build.flags.replace_cxxflags,
|
||||
vec!["-O2=>-O3", "-fno-rtti=>-fno-exceptions"]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,6 +270,17 @@ impl PackageSpec {
|
||||
self.build.flags.cflags = vec![s.to_string()];
|
||||
}
|
||||
}
|
||||
"replace_cflags" | "replace-cflags" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.replace_cflags = arr
|
||||
.iter()
|
||||
.filter_map(|x| x.as_str())
|
||||
.map(String::from)
|
||||
.collect();
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.replace_cflags = vec![s.to_string()];
|
||||
}
|
||||
}
|
||||
"cflags-lib32" | "cflags_lib32" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.cflags_lib32 = arr
|
||||
@@ -281,6 +292,17 @@ impl PackageSpec {
|
||||
self.build.flags.cflags_lib32 = vec![s.to_string()];
|
||||
}
|
||||
}
|
||||
"replace_cflags-lib32" | "replace_cflags_lib32" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.replace_cflags_lib32 = arr
|
||||
.iter()
|
||||
.filter_map(|x| x.as_str())
|
||||
.map(String::from)
|
||||
.collect();
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.replace_cflags_lib32 = vec![s.to_string()];
|
||||
}
|
||||
}
|
||||
"cxxflags" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.cxxflags = arr
|
||||
@@ -292,6 +314,17 @@ impl PackageSpec {
|
||||
self.build.flags.cxxflags = vec![s.to_string()];
|
||||
}
|
||||
}
|
||||
"replace_cxxflags" | "replace-cxxflags" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.replace_cxxflags = arr
|
||||
.iter()
|
||||
.filter_map(|x| x.as_str())
|
||||
.map(String::from)
|
||||
.collect();
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.replace_cxxflags = vec![s.to_string()];
|
||||
}
|
||||
}
|
||||
"cxxflags-lib32" | "cxxflags_lib32" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.cxxflags_lib32 = arr
|
||||
@@ -303,6 +336,17 @@ impl PackageSpec {
|
||||
self.build.flags.cxxflags_lib32 = vec![s.to_string()];
|
||||
}
|
||||
}
|
||||
"replace_cxxflags-lib32" | "replace_cxxflags_lib32" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.replace_cxxflags_lib32 = arr
|
||||
.iter()
|
||||
.filter_map(|x| x.as_str())
|
||||
.map(String::from)
|
||||
.collect();
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.replace_cxxflags_lib32 = vec![s.to_string()];
|
||||
}
|
||||
}
|
||||
"ldflags" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.ldflags = arr
|
||||
@@ -314,6 +358,17 @@ impl PackageSpec {
|
||||
self.build.flags.ldflags = vec![s.to_string()];
|
||||
}
|
||||
}
|
||||
"replace_ldflags" | "replace-ldflags" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.replace_ldflags = arr
|
||||
.iter()
|
||||
.filter_map(|x| x.as_str())
|
||||
.map(String::from)
|
||||
.collect();
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.replace_ldflags = vec![s.to_string()];
|
||||
}
|
||||
}
|
||||
"ltoflags" | "lto_flags" | "lto-flags" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.ltoflags = arr
|
||||
@@ -325,6 +380,39 @@ impl PackageSpec {
|
||||
self.build.flags.ltoflags = vec![s.to_string()];
|
||||
}
|
||||
}
|
||||
"replace_ltoflags" | "replace_lto-flags" | "replace_lto_flags" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.replace_ltoflags = arr
|
||||
.iter()
|
||||
.filter_map(|x| x.as_str())
|
||||
.map(String::from)
|
||||
.collect();
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.replace_ltoflags = vec![s.to_string()];
|
||||
}
|
||||
}
|
||||
"rustflags" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.rustflags = arr
|
||||
.iter()
|
||||
.filter_map(|x| x.as_str())
|
||||
.map(String::from)
|
||||
.collect();
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.rustflags = vec![s.to_string()];
|
||||
}
|
||||
}
|
||||
"replace_rustflags" | "replace-rustflags" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.replace_rustflags = arr
|
||||
.iter()
|
||||
.filter_map(|x| x.as_str())
|
||||
.map(String::from)
|
||||
.collect();
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.replace_rustflags = vec![s.to_string()];
|
||||
}
|
||||
}
|
||||
"keep" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.keep = arr
|
||||
@@ -746,6 +834,18 @@ impl PackageSpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
"replace_cflags" | "replace-cflags" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build
|
||||
.flags
|
||||
.replace_cflags
|
||||
.extend(arr.iter().filter_map(|x| x.as_str()).map(String::from));
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.replace_cflags.push(s.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
"cflags-lib32" | "cflags_lib32" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
@@ -758,6 +858,18 @@ impl PackageSpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
"replace_cflags-lib32" | "replace_cflags_lib32" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build
|
||||
.flags
|
||||
.replace_cflags_lib32
|
||||
.extend(arr.iter().filter_map(|x| x.as_str()).map(String::from));
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.replace_cflags_lib32.push(s.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
"cxxflags" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
@@ -770,6 +882,18 @@ impl PackageSpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
"replace_cxxflags" | "replace-cxxflags" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build
|
||||
.flags
|
||||
.replace_cxxflags
|
||||
.extend(arr.iter().filter_map(|x| x.as_str()).map(String::from));
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.replace_cxxflags.push(s.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
"cxxflags-lib32" | "cxxflags_lib32" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
@@ -782,6 +906,18 @@ impl PackageSpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
"replace_cxxflags-lib32" | "replace_cxxflags_lib32" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build
|
||||
.flags
|
||||
.replace_cxxflags_lib32
|
||||
.extend(arr.iter().filter_map(|x| x.as_str()).map(String::from));
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.replace_cxxflags_lib32.push(s.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
"ldflags" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
@@ -794,6 +930,18 @@ impl PackageSpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
"replace_ldflags" | "replace-ldflags" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build
|
||||
.flags
|
||||
.replace_ldflags
|
||||
.extend(arr.iter().filter_map(|x| x.as_str()).map(String::from));
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.replace_ldflags.push(s.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
"ltoflags" | "lto_flags" | "lto-flags" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
@@ -806,6 +954,18 @@ impl PackageSpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
"replace_ltoflags" | "replace_lto-flags" | "replace_lto_flags" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build
|
||||
.flags
|
||||
.replace_ltoflags
|
||||
.extend(arr.iter().filter_map(|x| x.as_str()).map(String::from));
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.replace_ltoflags.push(s.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
"keep" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
@@ -955,6 +1115,18 @@ impl PackageSpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
"replace_rustflags" | "replace-rustflags" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build
|
||||
.flags
|
||||
.replace_rustflags
|
||||
.extend(arr.iter().filter_map(|x| x.as_str()).map(String::from));
|
||||
} else if let Some(s) = v.as_str() {
|
||||
self.build.flags.replace_rustflags.push(s.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
"cc" => {
|
||||
if let Some(s) = values.last().and_then(|v| v.as_str()) {
|
||||
self.build.flags.cc = s.to_string();
|
||||
@@ -1941,7 +2113,9 @@ cc = "my-cc"
|
||||
ld = "ld.lld"
|
||||
CPP = "clang-cpp"
|
||||
cflags = ["-O2"]
|
||||
replace_cflags = ["-O2=>-O3"]
|
||||
cxxflags = ["-O2", "-pipe"]
|
||||
replace_cxxflags = ["-pipe=>-fPIC"]
|
||||
passthrough_env = ["RUSTFLAGS"]
|
||||
bindir = "/opt/bin"
|
||||
sbindir = "/opt/sbin"
|
||||
@@ -1954,6 +2128,9 @@ make_dirs = ["lib"]
|
||||
make_test_dirs = ["tests"]
|
||||
make_install_dirs = ["lib"]
|
||||
ltoflags = ["-flto=auto"]
|
||||
replace_ltoflags = ["auto=>thin"]
|
||||
rustflags = ["-C", "debuginfo=2"]
|
||||
replace_rustflags = ["debuginfo=2=>opt-level=2"]
|
||||
use_lto = true
|
||||
no_flags = true
|
||||
no_strip = true
|
||||
@@ -1971,10 +2148,22 @@ post_configure = ["echo configured"]
|
||||
"build.flags.cflags".to_string(),
|
||||
vec![toml::Value::String("-g".to_string())],
|
||||
);
|
||||
config.appends.insert(
|
||||
"build.flags.replace_cflags".to_string(),
|
||||
vec![toml::Value::String(
|
||||
"-D_FORTIFY_SOURCE=3=_FORTIFY_SOURCE=2".to_string(),
|
||||
)],
|
||||
);
|
||||
config.appends.insert(
|
||||
"build.flags.cxxflags".to_string(),
|
||||
vec![toml::Value::String("-stdlib=libc++".to_string())],
|
||||
);
|
||||
config.appends.insert(
|
||||
"build.flags.replace_cxxflags".to_string(),
|
||||
vec![toml::Value::String(
|
||||
"-stdlib=libc++=>-stdlib=libstdc++".to_string(),
|
||||
)],
|
||||
);
|
||||
config.appends.insert(
|
||||
"build.flags.rustflags".to_string(),
|
||||
vec![toml::Value::Array(vec![
|
||||
@@ -1982,6 +2171,10 @@ post_configure = ["echo configured"]
|
||||
toml::Value::String("opt-level=3".to_string()),
|
||||
])],
|
||||
);
|
||||
config.appends.insert(
|
||||
"build.flags.replace_rustflags".to_string(),
|
||||
vec![toml::Value::String("opt-level=3=>opt-level=z".to_string())],
|
||||
);
|
||||
config.appends.insert(
|
||||
"build.flags.keep".to_string(),
|
||||
vec![toml::Value::Array(vec![toml::Value::String(
|
||||
@@ -1994,6 +2187,12 @@ post_configure = ["echo configured"]
|
||||
"-fno-fat-lto-objects".to_string(),
|
||||
)])],
|
||||
);
|
||||
config.appends.insert(
|
||||
"build.flags.replace_ltoflags".to_string(),
|
||||
vec![toml::Value::String(
|
||||
"-fno-fat-lto-objects=>-flto-jobs=8".to_string(),
|
||||
)],
|
||||
);
|
||||
config.appends.insert(
|
||||
"build.flags.use_lto".to_string(),
|
||||
vec![toml::Value::Boolean(false)],
|
||||
@@ -2068,6 +2267,18 @@ post_configure = ["echo configured"]
|
||||
assert_eq!(spec.build.flags.cpp, "clang-cpp");
|
||||
assert!(spec.build.flags.cflags.contains(&"-O2".to_string()));
|
||||
assert!(spec.build.flags.cflags.contains(&"-g".to_string()));
|
||||
assert!(
|
||||
spec.build
|
||||
.flags
|
||||
.replace_cflags
|
||||
.contains(&"-O2=>-O3".to_string())
|
||||
);
|
||||
assert!(
|
||||
spec.build
|
||||
.flags
|
||||
.replace_cflags
|
||||
.contains(&"-D_FORTIFY_SOURCE=3=_FORTIFY_SOURCE=2".to_string())
|
||||
);
|
||||
assert!(spec.build.flags.cxxflags.contains(&"-O2".to_string()));
|
||||
assert!(spec.build.flags.cxxflags.contains(&"-pipe".to_string()));
|
||||
assert!(
|
||||
@@ -2076,13 +2287,43 @@ post_configure = ["echo configured"]
|
||||
.cxxflags
|
||||
.contains(&"-stdlib=libc++".to_string())
|
||||
);
|
||||
assert!(
|
||||
spec.build
|
||||
.flags
|
||||
.replace_cxxflags
|
||||
.contains(&"-pipe=>-fPIC".to_string())
|
||||
);
|
||||
assert!(
|
||||
spec.build
|
||||
.flags
|
||||
.replace_cxxflags
|
||||
.contains(&"-stdlib=libc++=>-stdlib=libstdc++".to_string())
|
||||
);
|
||||
assert!(spec.build.flags.rustflags.contains(&"-C".to_string()));
|
||||
assert!(
|
||||
spec.build
|
||||
.flags
|
||||
.rustflags
|
||||
.contains(&"debuginfo=2".to_string())
|
||||
);
|
||||
assert!(
|
||||
spec.build
|
||||
.flags
|
||||
.rustflags
|
||||
.contains(&"opt-level=3".to_string())
|
||||
);
|
||||
assert!(
|
||||
spec.build
|
||||
.flags
|
||||
.replace_rustflags
|
||||
.contains(&"debuginfo=2=>opt-level=2".to_string())
|
||||
);
|
||||
assert!(
|
||||
spec.build
|
||||
.flags
|
||||
.replace_rustflags
|
||||
.contains(&"opt-level=3=>opt-level=z".to_string())
|
||||
);
|
||||
assert!(
|
||||
spec.build
|
||||
.flags
|
||||
@@ -2095,6 +2336,18 @@ post_configure = ["echo configured"]
|
||||
.ltoflags
|
||||
.contains(&"-fno-fat-lto-objects".to_string())
|
||||
);
|
||||
assert!(
|
||||
spec.build
|
||||
.flags
|
||||
.replace_ltoflags
|
||||
.contains(&"auto=>thin".to_string())
|
||||
);
|
||||
assert!(
|
||||
spec.build
|
||||
.flags
|
||||
.replace_ltoflags
|
||||
.contains(&"-fno-fat-lto-objects=>-flto-jobs=8".to_string())
|
||||
);
|
||||
assert!(!spec.build.flags.use_lto);
|
||||
assert!(spec.build.flags.no_flags);
|
||||
assert!(!spec.build.flags.no_strip);
|
||||
@@ -2707,9 +2960,13 @@ extract_dir = "foo"
|
||||
type = "custom"
|
||||
|
||||
[build.flags]
|
||||
replace_cflags = ["-O2=>-O3"]
|
||||
replace_rustflags = ["debuginfo=2=>opt-level=2"]
|
||||
cxxflags = ["-O2"]
|
||||
cxxflags += [ "-Wno-gnu-statement-expression-from-macro-expansion" ]
|
||||
ldflags += "-Wl,--as-needed"
|
||||
replace_cflags += [ "_FORTIFY_SOURCE=3=_FORTIFY_SOURCE=2" ]
|
||||
replace_rustflags += "opt-level=3=>opt-level=z"
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -2726,6 +2983,20 @@ ldflags += "-Wl,--as-needed"
|
||||
spec.build.flags.ldflags,
|
||||
vec!["-Wl,--as-needed".to_string()]
|
||||
);
|
||||
assert_eq!(
|
||||
spec.build.flags.replace_cflags,
|
||||
vec![
|
||||
"-O2=>-O3".to_string(),
|
||||
"_FORTIFY_SOURCE=3=_FORTIFY_SOURCE=2".to_string()
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
spec.build.flags.replace_rustflags,
|
||||
vec![
|
||||
"debuginfo=2=>opt-level=2".to_string(),
|
||||
"opt-level=3=>opt-level=z".to_string()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -3259,8 +3530,19 @@ pub enum BuildType {
|
||||
/// Build flags and toolchain configuration
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub struct BuildFlags {
|
||||
/// Extra flags exported to `CFLAGS`.
|
||||
#[serde(default, deserialize_with = "deserialize_string_or_array")]
|
||||
pub cflags: Vec<String>,
|
||||
/// Ordered replacement rules applied to `cflags` before export.
|
||||
///
|
||||
/// Each entry may use `old=>new`. Plain `old=new` is also accepted and
|
||||
/// disambiguated against the current flag set when possible.
|
||||
#[serde(
|
||||
default,
|
||||
alias = "replace-cflags",
|
||||
deserialize_with = "deserialize_string_or_array_no_split"
|
||||
)]
|
||||
pub replace_cflags: Vec<String>,
|
||||
/// Extra flags exported to `CFLAGS` only for the lib32 build variant.
|
||||
#[serde(
|
||||
default,
|
||||
@@ -3271,9 +3553,25 @@ pub struct BuildFlags {
|
||||
deserialize_with = "deserialize_string_or_array"
|
||||
)]
|
||||
pub cflags_lib32: Vec<String>,
|
||||
/// Ordered replacement rules applied to lib32-only `cflags`.
|
||||
#[serde(
|
||||
default,
|
||||
alias = "replace-cflags-lib32",
|
||||
alias = "replace_cflags-lib32",
|
||||
alias = "replace_cflags_lib32",
|
||||
deserialize_with = "deserialize_string_or_array_no_split"
|
||||
)]
|
||||
pub replace_cflags_lib32: Vec<String>,
|
||||
/// Extra flags exported to `CXXFLAGS`.
|
||||
#[serde(default, deserialize_with = "deserialize_string_or_array")]
|
||||
pub cxxflags: Vec<String>,
|
||||
/// Ordered replacement rules applied to `cxxflags` before export.
|
||||
#[serde(
|
||||
default,
|
||||
alias = "replace-cxxflags",
|
||||
deserialize_with = "deserialize_string_or_array_no_split"
|
||||
)]
|
||||
pub replace_cxxflags: Vec<String>,
|
||||
/// Extra flags exported to `CXXFLAGS` only for the lib32 build variant.
|
||||
#[serde(
|
||||
default,
|
||||
@@ -3284,8 +3582,25 @@ pub struct BuildFlags {
|
||||
deserialize_with = "deserialize_string_or_array"
|
||||
)]
|
||||
pub cxxflags_lib32: Vec<String>,
|
||||
/// Ordered replacement rules applied to lib32-only `cxxflags`.
|
||||
#[serde(
|
||||
default,
|
||||
alias = "replace-cxxflags-lib32",
|
||||
alias = "replace_cxxflags-lib32",
|
||||
alias = "replace_cxxflags_lib32",
|
||||
deserialize_with = "deserialize_string_or_array_no_split"
|
||||
)]
|
||||
pub replace_cxxflags_lib32: Vec<String>,
|
||||
/// Extra flags exported to `LDFLAGS`.
|
||||
#[serde(default, deserialize_with = "deserialize_string_or_array")]
|
||||
pub ldflags: Vec<String>,
|
||||
/// Ordered replacement rules applied to `ldflags` before export.
|
||||
#[serde(
|
||||
default,
|
||||
alias = "replace-ldflags",
|
||||
deserialize_with = "deserialize_string_or_array_no_split"
|
||||
)]
|
||||
pub replace_ldflags: Vec<String>,
|
||||
/// Link-time optimization flags exported to `LTOFLAGS`.
|
||||
///
|
||||
/// When `use_lto` is true (default), these flags are also appended to
|
||||
@@ -3298,6 +3613,15 @@ pub struct BuildFlags {
|
||||
deserialize_with = "deserialize_string_or_array"
|
||||
)]
|
||||
pub ltoflags: Vec<String>,
|
||||
/// Ordered replacement rules applied to `ltoflags` before export/injection.
|
||||
#[serde(
|
||||
default,
|
||||
alias = "replace-ltoflags",
|
||||
alias = "replace_lto-flags",
|
||||
alias = "replace_lto_flags",
|
||||
deserialize_with = "deserialize_string_or_array_no_split"
|
||||
)]
|
||||
pub replace_ltoflags: Vec<String>,
|
||||
/// Keep existing files and install package-provided replacement as `<path>.depotnew`.
|
||||
#[serde(default, deserialize_with = "deserialize_string_or_array")]
|
||||
pub keep: Vec<String>,
|
||||
@@ -3552,6 +3876,13 @@ pub struct BuildFlags {
|
||||
/// RUSTFLAGS environment variable
|
||||
#[serde(default, deserialize_with = "deserialize_string_or_array")]
|
||||
pub rustflags: Vec<String>,
|
||||
/// Ordered replacement rules applied to `rustflags` before export.
|
||||
#[serde(
|
||||
default,
|
||||
alias = "replace-rustflags",
|
||||
deserialize_with = "deserialize_string_or_array_no_split"
|
||||
)]
|
||||
pub replace_rustflags: Vec<String>,
|
||||
/// Additional cargo arguments (short name)
|
||||
#[serde(default)]
|
||||
pub cargs: Vec<String>,
|
||||
@@ -3617,11 +3948,17 @@ impl Default for BuildFlags {
|
||||
fn default() -> Self {
|
||||
BuildFlags {
|
||||
cflags: Vec::new(),
|
||||
replace_cflags: Vec::new(),
|
||||
cflags_lib32: Vec::new(),
|
||||
replace_cflags_lib32: Vec::new(),
|
||||
cxxflags: Vec::new(),
|
||||
replace_cxxflags: Vec::new(),
|
||||
cxxflags_lib32: Vec::new(),
|
||||
replace_cxxflags_lib32: Vec::new(),
|
||||
ldflags: Vec::new(),
|
||||
replace_ldflags: Vec::new(),
|
||||
ltoflags: Vec::new(),
|
||||
replace_ltoflags: Vec::new(),
|
||||
keep: Vec::new(),
|
||||
use_lto: default_use_lto(),
|
||||
no_flags: false,
|
||||
@@ -3671,6 +4008,7 @@ impl Default for BuildFlags {
|
||||
profile: default_profile(),
|
||||
target: String::new(),
|
||||
rustflags: Vec::new(),
|
||||
replace_rustflags: Vec::new(),
|
||||
cargs: Vec::new(),
|
||||
bindir: default_bindir(),
|
||||
sbindir: String::new(),
|
||||
|
||||
Reference in New Issue
Block a user