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() {
|
if !flags.prefix.is_empty() {
|
||||||
set_env_var(&mut env_vars, "PREFIX", flags.prefix.clone());
|
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(&mut env_vars, "DEPOT_ROOTFS", flags.rootfs.clone());
|
||||||
set_env_var(
|
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]
|
#[test]
|
||||||
fn test_standard_build_env_exports_passthrough_env() {
|
fn test_standard_build_env_exports_passthrough_env() {
|
||||||
let mut spec = mk_spec(Vec::new(), Vec::new());
|
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()),
|
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() {
|
if !spec.build.flags.make_vars.is_empty() {
|
||||||
flags_tbl.insert(
|
flags_tbl.insert(
|
||||||
"make_vars".into(),
|
"make_vars".into(),
|
||||||
@@ -1475,6 +1481,7 @@ mod tests {
|
|||||||
flags.no_delete_static = true;
|
flags.no_delete_static = true;
|
||||||
flags.no_compress_man = true;
|
flags.no_compress_man = true;
|
||||||
flags.skip_tests = true;
|
flags.skip_tests = true;
|
||||||
|
flags.makeflags = "-j12 --output-sync=target".into();
|
||||||
flags.make_vars = vec!["V=1".into()];
|
flags.make_vars = vec!["V=1".into()];
|
||||||
flags.make_dirs = vec!["lib".into(), "libelf".into()];
|
flags.make_dirs = vec!["lib".into(), "libelf".into()];
|
||||||
flags.make_test_vars = vec!["TESTS=unit".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_delete_static = true"));
|
||||||
assert!(toml.contains("no_compress_man = true"));
|
assert!(toml.contains("no_compress_man = true"));
|
||||||
assert!(toml.contains("skip_tests = true"));
|
assert!(toml.contains("skip_tests = true"));
|
||||||
|
assert!(toml.contains("makeflags = \"-j12 --output-sync=target\""));
|
||||||
assert!(toml.contains("make_vars = ["));
|
assert!(toml.contains("make_vars = ["));
|
||||||
assert!(toml.contains("make_dirs = ["));
|
assert!(toml.contains("make_dirs = ["));
|
||||||
assert!(toml.contains("make_test_vars = ["));
|
assert!(toml.contains("make_test_vars = ["));
|
||||||
|
|||||||
@@ -346,6 +346,19 @@ impl PackageSpec {
|
|||||||
self.build.flags.carch = s.to_string();
|
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" => {
|
"make_vars" | "make-vars" | "make_build_vars" | "make-build-vars" => {
|
||||||
if let Some(arr) = v.as_array() {
|
if let Some(arr) = v.as_array() {
|
||||||
self.build.flags.make_vars = arr
|
self.build.flags.make_vars = arr
|
||||||
@@ -860,6 +873,22 @@ impl PackageSpec {
|
|||||||
self.build.flags.carch = s.to_string();
|
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" => {
|
"make_vars" | "make-vars" | "make_build_vars" | "make-build-vars" => {
|
||||||
for v in values {
|
for v in values {
|
||||||
if let Some(arr) = v.as_array() {
|
if let Some(arr) = v.as_array() {
|
||||||
@@ -1652,6 +1681,7 @@ cc = "my-cc"
|
|||||||
cflags = ["-O2"]
|
cflags = ["-O2"]
|
||||||
cxxflags = ["-O2", "-pipe"]
|
cxxflags = ["-O2", "-pipe"]
|
||||||
passthrough_env = ["RUSTFLAGS"]
|
passthrough_env = ["RUSTFLAGS"]
|
||||||
|
makeflags = "-j8"
|
||||||
make_vars = ["V=1"]
|
make_vars = ["V=1"]
|
||||||
make_dirs = ["lib"]
|
make_dirs = ["lib"]
|
||||||
make_test_dirs = ["tests"]
|
make_test_dirs = ["tests"]
|
||||||
@@ -1709,6 +1739,10 @@ post_configure = ["echo configured"]
|
|||||||
"build.flags.make_test_vars".to_string(),
|
"build.flags.make_test_vars".to_string(),
|
||||||
vec![toml::Value::String("TESTS=smoke".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(
|
config.appends.insert(
|
||||||
"build.flags.make_dirs".to_string(),
|
"build.flags.make_dirs".to_string(),
|
||||||
vec![toml::Value::String("libelf".to_string())],
|
vec![toml::Value::String("libelf".to_string())],
|
||||||
@@ -1782,6 +1816,7 @@ post_configure = ["echo configured"]
|
|||||||
.passthrough_env
|
.passthrough_env
|
||||||
.contains(&"CARGO_HOME".to_string())
|
.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_vars.contains(&"V=1".to_string()));
|
||||||
assert!(spec.build.flags.make_dirs.contains(&"lib".to_string()));
|
assert!(spec.build.flags.make_dirs.contains(&"lib".to_string()));
|
||||||
assert!(spec.build.flags.make_dirs.contains(&"libelf".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]
|
#[test]
|
||||||
fn test_chost_cbuild_overrides() {
|
fn test_chost_cbuild_overrides() {
|
||||||
let mut spec = mk_spec("foo", "1.0");
|
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"
|
/// CPU architecture short name (CARCH equivalent), e.g. "x86_64", "aarch64"
|
||||||
#[serde(default = "default_carch")]
|
#[serde(default = "default_carch")]
|
||||||
pub carch: String,
|
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"].
|
/// Variable overrides passed directly to `make` (compile step), e.g. ["V=1", "CC=clang"].
|
||||||
#[serde(
|
#[serde(
|
||||||
default,
|
default,
|
||||||
@@ -3022,6 +3099,7 @@ impl Default for BuildFlags {
|
|||||||
chost: String::new(),
|
chost: String::new(),
|
||||||
cbuild: String::new(),
|
cbuild: String::new(),
|
||||||
carch: default_carch(),
|
carch: default_carch(),
|
||||||
|
makeflags: String::new(),
|
||||||
make_vars: Vec::new(),
|
make_vars: Vec::new(),
|
||||||
make_exec: String::new(),
|
make_exec: String::new(),
|
||||||
make_target: 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>
|
fn deserialize_boolish<'de, D>(deserializer: D) -> std::result::Result<bool, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
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 {
|
fn default_cc() -> String {
|
||||||
// Prefer clang if available (supports -print-resource-dir and other useful flags)
|
// Prefer clang if available (supports -print-resource-dir and other useful flags)
|
||||||
if std::process::Command::new("which")
|
if std::process::Command::new("which")
|
||||||
|
|||||||
Reference in New Issue
Block a user