deps: resolve :native against DEB_BUILD_ARCH in cross builds
CheckOpts had no build-arch concept: the build-side facts and :native qualifiers resolved against the host arch, so in a cross build (-a armhf on amd64) 'Build-Depends: foo:native' looked for an armhf package where dpkg-checkbuilddeps looks for an amd64 one. CheckOpts gains build_arch (DEB_BUILD_ARCH), used for :native and the dpkg status attribution; bracketed arch restrictions keep evaluating against the host arch.
This commit is contained in:
+7
-1
@@ -354,6 +354,10 @@ pub fn run_source_build(
|
|||||||
.get("DEB_HOST_ARCH")
|
.get("DEB_HOST_ARCH")
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_else(|| crate::debian::arch::native().unwrap_or_default()),
|
.unwrap_or_else(|| crate::debian::arch::native().unwrap_or_default()),
|
||||||
|
build_arch: arch_vars
|
||||||
|
.get("DEB_BUILD_ARCH")
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_else(|| crate::debian::arch::native().unwrap_or_default()),
|
||||||
build_profiles: profiles.clone(),
|
build_profiles: profiles.clone(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
@@ -1599,8 +1603,10 @@ mod differential_tests {
|
|||||||
}
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
let host_arch = crate::debian::arch::native().unwrap_or_else(|_| "amd64".into());
|
||||||
let opts = crate::debian::deps::CheckOpts {
|
let opts = crate::debian::deps::CheckOpts {
|
||||||
host_arch: crate::debian::arch::native().unwrap_or_else(|_| "amd64".into()),
|
host_arch: host_arch.clone(),
|
||||||
|
build_arch: host_arch,
|
||||||
build_profiles: profiles,
|
build_profiles: profiles,
|
||||||
ignore_arch,
|
ignore_arch,
|
||||||
ignore_indep,
|
ignore_indep,
|
||||||
|
|||||||
+77
-4
@@ -785,8 +785,15 @@ impl Facts {
|
|||||||
/// Options for [`check_build_depends`].
|
/// Options for [`check_build_depends`].
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct CheckOpts {
|
pub struct CheckOpts {
|
||||||
/// Host architecture (defaults to the native architecture).
|
/// Host architecture, i.e. `DEB_HOST_ARCH`: the architecture the
|
||||||
|
/// packages are built FOR (defaults to the native architecture).
|
||||||
|
/// Bracketed `foo [arch]` restrictions evaluate against it.
|
||||||
pub host_arch: String,
|
pub host_arch: String,
|
||||||
|
/// Build architecture, i.e. `DEB_BUILD_ARCH`: the architecture the
|
||||||
|
/// build runs ON (defaults to the native architecture). `:native`
|
||||||
|
/// dependency qualifiers and the dpkg status attribution of the
|
||||||
|
/// build-side facts resolve against it.
|
||||||
|
pub build_arch: String,
|
||||||
/// Active build profiles.
|
/// Active build profiles.
|
||||||
pub build_profiles: Vec<String>,
|
pub build_profiles: Vec<String>,
|
||||||
/// Ignore `Build-Depends-Arch`/`Build-Conflicts-Arch` (`-A`).
|
/// Ignore `Build-Depends-Arch`/`Build-Conflicts-Arch` (`-A`).
|
||||||
@@ -804,6 +811,7 @@ impl Default for CheckOpts {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
CheckOpts {
|
CheckOpts {
|
||||||
host_arch: arch::native().unwrap_or_default(),
|
host_arch: arch::native().unwrap_or_default(),
|
||||||
|
build_arch: arch::native().unwrap_or_default(),
|
||||||
build_profiles: Vec::new(),
|
build_profiles: Vec::new(),
|
||||||
ignore_arch: false,
|
ignore_arch: false,
|
||||||
ignore_indep: false,
|
ignore_indep: false,
|
||||||
@@ -904,14 +912,14 @@ pub fn check_build_depends(control: &ControlInfo, opts: &CheckOpts) -> Result<Un
|
|||||||
let bc_value = bc_parts.join(", ");
|
let bc_value = bc_parts.join(", ");
|
||||||
|
|
||||||
let status_path = opts.admindir.join("status");
|
let status_path = opts.admindir.join("status");
|
||||||
let facts = Facts::load_status(&status_path, &opts.host_arch, &opts.host_arch)?;
|
let facts = Facts::load_status(&status_path, &opts.host_arch, &opts.build_arch)?;
|
||||||
|
|
||||||
let mut report = UnmetReport::default();
|
let mut report = UnmetReport::default();
|
||||||
|
|
||||||
if !bd_value.trim().is_empty() {
|
if !bd_value.trim().is_empty() {
|
||||||
let parse_opts = ParseOpts {
|
let parse_opts = ParseOpts {
|
||||||
host_arch: opts.host_arch.clone(),
|
host_arch: opts.host_arch.clone(),
|
||||||
build_arch: opts.host_arch.clone(),
|
build_arch: opts.build_arch.clone(),
|
||||||
build_profiles: opts.build_profiles.clone(),
|
build_profiles: opts.build_profiles.clone(),
|
||||||
reduce_restrictions: true,
|
reduce_restrictions: true,
|
||||||
union: false,
|
union: false,
|
||||||
@@ -933,7 +941,7 @@ pub fn check_build_depends(control: &ControlInfo, opts: &CheckOpts) -> Result<Un
|
|||||||
if !bc_value.trim().is_empty() {
|
if !bc_value.trim().is_empty() {
|
||||||
let parse_opts = ParseOpts {
|
let parse_opts = ParseOpts {
|
||||||
host_arch: opts.host_arch.clone(),
|
host_arch: opts.host_arch.clone(),
|
||||||
build_arch: opts.host_arch.clone(),
|
build_arch: opts.build_arch.clone(),
|
||||||
build_profiles: opts.build_profiles.clone(),
|
build_profiles: opts.build_profiles.clone(),
|
||||||
reduce_restrictions: true,
|
reduce_restrictions: true,
|
||||||
union: true,
|
union: true,
|
||||||
@@ -1363,4 +1371,69 @@ Architecture: amd64
|
|||||||
let report = check_build_depends(&control_conflict, &opts).unwrap();
|
let report = check_build_depends(&control_conflict, &opts).unwrap();
|
||||||
assert_eq!(report.message(), "unmet build conflicts: mypackage");
|
assert_eq!(report.message(), "unmet build conflicts: mypackage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_build_depends_cross_native_qualifier() {
|
||||||
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
let admindir = dir.path();
|
||||||
|
|
||||||
|
// Cross build: armhf packages built ON an amd64 machine, so
|
||||||
|
// DEB_HOST_ARCH=armhf but DEB_BUILD_ARCH=amd64.
|
||||||
|
let opts = CheckOpts {
|
||||||
|
host_arch: "armhf".to_string(),
|
||||||
|
build_arch: "amd64".to_string(),
|
||||||
|
admindir: admindir.to_path_buf(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let control_for = |bd: &str| {
|
||||||
|
ControlInfo::parse_content(&format!(
|
||||||
|
"Source: t\nMaintainer: a <a@b.c>\nBuild-Depends: {bd}\n\nPackage: t\nArchitecture: any\nDescription: x\n y\n"
|
||||||
|
))
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
// foo is only installed for the build architecture, like a native
|
||||||
|
// toolchain package pulled in on the build machine.
|
||||||
|
std::fs::write(
|
||||||
|
admindir.join("status"),
|
||||||
|
"\
|
||||||
|
Package: foo
|
||||||
|
Status: install ok installed
|
||||||
|
Version: 1.0
|
||||||
|
Architecture: amd64
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// `:native` resolves against the BUILD architecture: satisfied even
|
||||||
|
// though the host architecture is armhf.
|
||||||
|
let report = check_build_depends(&control_for("foo:native"), &opts).unwrap();
|
||||||
|
assert!(report.is_ok());
|
||||||
|
|
||||||
|
// Bracketed architecture restrictions keep evaluating against the
|
||||||
|
// HOST architecture: the amd64 instance cannot satisfy `foo [armhf]`.
|
||||||
|
// (The applied restriction reduces away, per dpkg's reduce_arch.)
|
||||||
|
let report = check_build_depends(&control_for("foo [armhf]"), &opts).unwrap();
|
||||||
|
assert_eq!(report.message(), "unmet build dependencies: foo");
|
||||||
|
|
||||||
|
// Now foo is only installed for the host architecture.
|
||||||
|
std::fs::write(
|
||||||
|
admindir.join("status"),
|
||||||
|
"\
|
||||||
|
Package: foo
|
||||||
|
Status: install ok installed
|
||||||
|
Version: 1.0
|
||||||
|
Architecture: armhf
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// `:native` no longer matches: no amd64 instance is installed.
|
||||||
|
let report = check_build_depends(&control_for("foo:native"), &opts).unwrap();
|
||||||
|
assert_eq!(report.message(), "unmet build dependencies: foo:native");
|
||||||
|
|
||||||
|
// The host-arch restriction matches the armhf instance.
|
||||||
|
let report = check_build_depends(&control_for("foo [armhf]"), &opts).unwrap();
|
||||||
|
assert!(report.is_ok());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user