From a4be046aaac06cd013d8a350410da84678f058ce Mon Sep 17 00:00:00 2001 From: Valentin Haudiquet Date: Thu, 1 Oct 2026 22:23:55 +0200 Subject: [PATCH] deb: export the dpkg architecture environment for the rules The rules run outside dpkg-buildpackage, which exports none of the dpkg architecture variables anyway - only sbuild does. Packages using $(DEB_HOST_MULTIARCH) or $(DEB_BUILD_GNU_TYPE) without including /usr/share/dpkg/architecture.mk expanded them empty: micro's rules cd'd into 'obj-' and file configured --libdir=/usr/lib, putting its libraries where dh_install's multiarch glob could not find them. Run 'dpkg-architecture -s' in the build context and export the whole DEB_* set, sbuild-style, for native builds; cross builds already carry the target's set from cross::setup_environment, whose output parser this reuses. --- src/deb/cross.rs | 4 +++- src/deb/local.rs | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/deb/cross.rs b/src/deb/cross.rs index 5f8c721..5a28439 100644 --- a/src/deb/cross.rs +++ b/src/deb/cross.rs @@ -7,7 +7,9 @@ use std::sync::Arc; /// Parse 'dpkg-architecture' output (KEY=value lines) into a set of /// environment variables. Unexpected lines (e.g. warnings on stderr leaking /// into stdout) are skipped instead of causing a failure. -fn parse_dpkg_architecture_output(output: &str, env: &mut HashMap) { +/// Parse the `VAR=value; ...; export ...` output of `dpkg-architecture -s` +/// into `env`. +pub fn parse_dpkg_architecture_output(output: &str, env: &mut HashMap) { let env_var_regex = regex::Regex::new(r"(?.*)=(?.*)").unwrap(); for l in output.lines() { let Some(capture) = env_var_regex.captures(l) else { diff --git a/src/deb/local.rs b/src/deb/local.rs index e728f10..782a8e7 100644 --- a/src/deb/local.rs +++ b/src/deb/local.rs @@ -152,6 +152,25 @@ pub async fn build( log::debug!("Setting up environment for local cross build..."); cross::setup_environment(&mut env, arch, ctx.clone())?; cross::ensure_repositories(arch, series, pocket, mirror, ctx.clone())?; + } else { + // sbuild-style environment for debian/rules: the rules run outside + // dpkg-buildpackage, which exports none of the dpkg architecture + // variables — packages using $(DEB_HOST_MULTIARCH) and friends + // without including /usr/share/dpkg/architecture.mk would expand + // them empty. Cross builds already carry the target's set from + // cross::setup_environment. + let output = ctx + .command("dpkg-architecture") + .output() + .map_err(|e| format!("cannot run dpkg-architecture: {e}. Is 'dpkg-dev' installed?"))?; + if !output.status.success() { + return Err( + format!("'dpkg-architecture' failed with status: {}", output.status).into(), + ); + } + let dpkg_architecture = String::from_utf8(output.stdout) + .map_err(|e| format!("Invalid UTF-8 in dpkg-architecture output: {e}"))?; + cross::parse_dpkg_architecture_output(&dpkg_architecture, &mut env); } let mut sources = apt::sources::load(Some(ctx.clone()))?;