diff --git a/src/build/mod.rs b/src/build/mod.rs index 1df39c4..0938389 100644 --- a/src/build/mod.rs +++ b/src/build/mod.rs @@ -354,6 +354,10 @@ pub fn run_source_build( .get("DEB_HOST_ARCH") .cloned() .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(), ..Default::default() }; @@ -1599,8 +1603,10 @@ mod differential_tests { } i += 1; } + let host_arch = crate::debian::arch::native().unwrap_or_else(|_| "amd64".into()); 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, ignore_arch, ignore_indep, diff --git a/src/debian/deps.rs b/src/debian/deps.rs index 7dd90e1..59d8918 100644 --- a/src/debian/deps.rs +++ b/src/debian/deps.rs @@ -785,8 +785,15 @@ impl Facts { /// Options for [`check_build_depends`]. #[derive(Debug, Clone)] 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, + /// 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. pub build_profiles: Vec, /// Ignore `Build-Depends-Arch`/`Build-Conflicts-Arch` (`-A`). @@ -804,6 +811,7 @@ impl Default for CheckOpts { fn default() -> Self { CheckOpts { host_arch: arch::native().unwrap_or_default(), + build_arch: arch::native().unwrap_or_default(), build_profiles: Vec::new(), ignore_arch: false, ignore_indep: false, @@ -904,14 +912,14 @@ pub fn check_build_depends(control: &ControlInfo, opts: &CheckOpts) -> Result Result\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()); + } }