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.
This commit is contained in:
2026-10-01 22:23:55 +02:00
parent ca0782488f
commit a4be046aaa
2 changed files with 22 additions and 1 deletions
+3 -1
View File
@@ -7,7 +7,9 @@ use std::sync::Arc;
/// Parse 'dpkg-architecture' output (KEY=value lines) into a set of /// Parse 'dpkg-architecture' output (KEY=value lines) into a set of
/// environment variables. Unexpected lines (e.g. warnings on stderr leaking /// environment variables. Unexpected lines (e.g. warnings on stderr leaking
/// into stdout) are skipped instead of causing a failure. /// into stdout) are skipped instead of causing a failure.
fn parse_dpkg_architecture_output(output: &str, env: &mut HashMap<String, String>) { /// Parse the `VAR=value; ...; export ...` output of `dpkg-architecture -s`
/// into `env`.
pub fn parse_dpkg_architecture_output(output: &str, env: &mut HashMap<String, String>) {
let env_var_regex = regex::Regex::new(r"(?<key>.*)=(?<value>.*)").unwrap(); let env_var_regex = regex::Regex::new(r"(?<key>.*)=(?<value>.*)").unwrap();
for l in output.lines() { for l in output.lines() {
let Some(capture) = env_var_regex.captures(l) else { let Some(capture) = env_var_regex.captures(l) else {
+19
View File
@@ -152,6 +152,25 @@ pub async fn build(
log::debug!("Setting up environment for local cross build..."); log::debug!("Setting up environment for local cross build...");
cross::setup_environment(&mut env, arch, ctx.clone())?; cross::setup_environment(&mut env, arch, ctx.clone())?;
cross::ensure_repositories(arch, series, pocket, mirror, 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()))?; let mut sources = apt::sources::load(Some(ctx.clone()))?;