feat: add support for MAKEFLAGS in build flags and update TOML parsing
This commit is contained in:
@@ -78,6 +78,13 @@ pub fn standard_build_env(
|
||||
if !flags.prefix.is_empty() {
|
||||
set_env_var(&mut env_vars, "PREFIX", flags.prefix.clone());
|
||||
}
|
||||
if !flags.makeflags.trim().is_empty() {
|
||||
set_env_var(
|
||||
&mut env_vars,
|
||||
"MAKEFLAGS",
|
||||
flags.makeflags.trim().to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
set_env_var(&mut env_vars, "DEPOT_ROOTFS", flags.rootfs.clone());
|
||||
set_env_var(
|
||||
@@ -417,6 +424,19 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_standard_build_env_exports_makeflags() {
|
||||
let mut spec = mk_spec(Vec::new(), Vec::new());
|
||||
spec.build.flags.makeflags = "-j12 --output-sync=target".to_string();
|
||||
|
||||
let env = standard_build_env(&spec, None, true, true);
|
||||
assert!(
|
||||
env.iter()
|
||||
.any(|(k, v)| k == "MAKEFLAGS" && v == "-j12 --output-sync=target"),
|
||||
"expected MAKEFLAGS to be exported from build flags"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_standard_build_env_exports_passthrough_env() {
|
||||
let mut spec = mk_spec(Vec::new(), Vec::new());
|
||||
|
||||
@@ -972,6 +972,12 @@ pub fn spec_to_minimal_toml(spec: &PackageSpec) -> anyhow::Result<String> {
|
||||
Value::String(spec.build.flags.carch.clone()),
|
||||
);
|
||||
}
|
||||
if !spec.build.flags.makeflags.is_empty() {
|
||||
flags_tbl.insert(
|
||||
"makeflags".into(),
|
||||
Value::String(spec.build.flags.makeflags.clone()),
|
||||
);
|
||||
}
|
||||
if !spec.build.flags.make_vars.is_empty() {
|
||||
flags_tbl.insert(
|
||||
"make_vars".into(),
|
||||
@@ -1475,6 +1481,7 @@ mod tests {
|
||||
flags.no_delete_static = true;
|
||||
flags.no_compress_man = true;
|
||||
flags.skip_tests = true;
|
||||
flags.makeflags = "-j12 --output-sync=target".into();
|
||||
flags.make_vars = vec!["V=1".into()];
|
||||
flags.make_dirs = vec!["lib".into(), "libelf".into()];
|
||||
flags.make_test_vars = vec!["TESTS=unit".into()];
|
||||
@@ -1533,6 +1540,7 @@ mod tests {
|
||||
assert!(toml.contains("no_delete_static = true"));
|
||||
assert!(toml.contains("no_compress_man = true"));
|
||||
assert!(toml.contains("skip_tests = true"));
|
||||
assert!(toml.contains("makeflags = \"-j12 --output-sync=target\""));
|
||||
assert!(toml.contains("make_vars = ["));
|
||||
assert!(toml.contains("make_dirs = ["));
|
||||
assert!(toml.contains("make_test_vars = ["));
|
||||
|
||||
@@ -346,6 +346,19 @@ impl PackageSpec {
|
||||
self.build.flags.carch = s.to_string();
|
||||
}
|
||||
}
|
||||
"makeflags" | "make_flags" | "make-flags" => {
|
||||
if let Some(s) = v.as_str() {
|
||||
self.build.flags.makeflags = s.to_string();
|
||||
} else if let Some(arr) = v.as_array() {
|
||||
self.build.flags.makeflags = arr
|
||||
.iter()
|
||||
.filter_map(|x| x.as_str())
|
||||
.map(str::trim)
|
||||
.filter(|x| !x.is_empty())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
}
|
||||
}
|
||||
"make_vars" | "make-vars" | "make_build_vars" | "make-build-vars" => {
|
||||
if let Some(arr) = v.as_array() {
|
||||
self.build.flags.make_vars = arr
|
||||
@@ -860,6 +873,22 @@ impl PackageSpec {
|
||||
self.build.flags.carch = s.to_string();
|
||||
}
|
||||
}
|
||||
"makeflags" | "make_flags" | "make-flags" | "MAKEFLAGS" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
let joined = arr
|
||||
.iter()
|
||||
.filter_map(|x| x.as_str())
|
||||
.map(str::trim)
|
||||
.filter(|x| !x.is_empty())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
append_whitespace_separated(&mut self.build.flags.makeflags, &joined);
|
||||
} else if let Some(s) = v.as_str() {
|
||||
append_whitespace_separated(&mut self.build.flags.makeflags, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
"make_vars" | "make-vars" | "make_build_vars" | "make-build-vars" => {
|
||||
for v in values {
|
||||
if let Some(arr) = v.as_array() {
|
||||
@@ -1652,6 +1681,7 @@ cc = "my-cc"
|
||||
cflags = ["-O2"]
|
||||
cxxflags = ["-O2", "-pipe"]
|
||||
passthrough_env = ["RUSTFLAGS"]
|
||||
makeflags = "-j8"
|
||||
make_vars = ["V=1"]
|
||||
make_dirs = ["lib"]
|
||||
make_test_dirs = ["tests"]
|
||||
@@ -1709,6 +1739,10 @@ post_configure = ["echo configured"]
|
||||
"build.flags.make_test_vars".to_string(),
|
||||
vec![toml::Value::String("TESTS=smoke".to_string())],
|
||||
);
|
||||
config.appends.insert(
|
||||
"build.flags.makeflags".to_string(),
|
||||
vec![toml::Value::String("--output-sync=target".to_string())],
|
||||
);
|
||||
config.appends.insert(
|
||||
"build.flags.make_dirs".to_string(),
|
||||
vec![toml::Value::String("libelf".to_string())],
|
||||
@@ -1782,6 +1816,7 @@ post_configure = ["echo configured"]
|
||||
.passthrough_env
|
||||
.contains(&"CARGO_HOME".to_string())
|
||||
);
|
||||
assert_eq!(spec.build.flags.makeflags, "-j8 --output-sync=target");
|
||||
assert!(spec.build.flags.make_vars.contains(&"V=1".to_string()));
|
||||
assert!(spec.build.flags.make_dirs.contains(&"lib".to_string()));
|
||||
assert!(spec.build.flags.make_dirs.contains(&"libelf".to_string()));
|
||||
@@ -2378,6 +2413,39 @@ make_install_dirs = ["lib", "apps"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_makeflags_from_spec() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let path = tmp.path().join("pkg.toml");
|
||||
|
||||
std::fs::write(
|
||||
&path,
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "1.0"
|
||||
description = "d"
|
||||
homepage = "h"
|
||||
license = "MIT"
|
||||
|
||||
[source]
|
||||
url = "https://example.com/foo.tar.gz"
|
||||
sha256 = "skip"
|
||||
extract_dir = "foo"
|
||||
|
||||
[build]
|
||||
type = "autotools"
|
||||
|
||||
[build.flags]
|
||||
MAKEFLAGS = ["-j12", "--output-sync=target"]
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let spec = PackageSpec::from_file(&path).unwrap();
|
||||
assert_eq!(spec.build.flags.makeflags, "-j12 --output-sync=target");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chost_cbuild_overrides() {
|
||||
let mut spec = mk_spec("foo", "1.0");
|
||||
@@ -2857,6 +2925,15 @@ pub struct BuildFlags {
|
||||
/// CPU architecture short name (CARCH equivalent), e.g. "x86_64", "aarch64"
|
||||
#[serde(default = "default_carch")]
|
||||
pub carch: String,
|
||||
/// MAKEFLAGS environment variable passed to build commands.
|
||||
#[serde(
|
||||
default,
|
||||
alias = "make-flags",
|
||||
alias = "make_flags",
|
||||
alias = "MAKEFLAGS",
|
||||
deserialize_with = "deserialize_string_or_array_joined"
|
||||
)]
|
||||
pub makeflags: String,
|
||||
/// Variable overrides passed directly to `make` (compile step), e.g. ["V=1", "CC=clang"].
|
||||
#[serde(
|
||||
default,
|
||||
@@ -3022,6 +3099,7 @@ impl Default for BuildFlags {
|
||||
chost: String::new(),
|
||||
cbuild: String::new(),
|
||||
carch: default_carch(),
|
||||
makeflags: String::new(),
|
||||
make_vars: Vec::new(),
|
||||
make_exec: String::new(),
|
||||
make_target: String::new(),
|
||||
@@ -3089,6 +3167,31 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_string_or_array_joined<'de, D>(
|
||||
deserializer: D,
|
||||
) -> std::result::Result<String, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum StringOrArray {
|
||||
String(String),
|
||||
Array(Vec<String>),
|
||||
}
|
||||
|
||||
match Option::<StringOrArray>::deserialize(deserializer)? {
|
||||
Some(StringOrArray::String(s)) => Ok(s),
|
||||
Some(StringOrArray::Array(a)) => Ok(a
|
||||
.iter()
|
||||
.map(|s| s.trim())
|
||||
.filter(|s| !s.is_empty())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")),
|
||||
None => Ok(String::new()),
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_boolish<'de, D>(deserializer: D) -> std::result::Result<bool, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
@@ -3127,6 +3230,19 @@ fn toml_value_as_boolish(value: &toml::Value) -> Option<bool> {
|
||||
})
|
||||
}
|
||||
|
||||
fn append_whitespace_separated(dst: &mut String, value: &str) {
|
||||
let trimmed = value.trim();
|
||||
if trimmed.is_empty() {
|
||||
return;
|
||||
}
|
||||
if dst.is_empty() {
|
||||
dst.push_str(trimmed);
|
||||
} else {
|
||||
dst.push(' ');
|
||||
dst.push_str(trimmed);
|
||||
}
|
||||
}
|
||||
|
||||
fn default_cc() -> String {
|
||||
// Prefer clang if available (supports -print-resource-dir and other useful flags)
|
||||
if std::process::Command::new("which")
|
||||
|
||||
Reference in New Issue
Block a user