deb: scope the arch-indep build-dep pass to the host arch in cross builds
CI / build (push) Successful in 2m49s
CI / test (push) Skipped
CI / snap (push) Failing after 11s

Without --host-architecture, the second build-dep pass re-resolves the
whole Build-Depends field for the native architecture: apt swaps
host-arch -dev packages for native ones (e.g. libcurl4-gnutls-dev,
whose arch-differing curl-config makes dpkg refuse the co-install) and
breaks the cross build environment.

Per dpkg-checkbuilddeps, both Build-Depends and Build-Depends-Indep
resolve for the host architecture in cross mode, so pass
--host-architecture to the second pass as well. Skip the pass entirely
when the source declares no Build-Depends-Indep.

Add an end-to-end regression test building a package that declares
libdb-dev in both fields and links a host-arch binary against it: the
test only passes if the arch-indep pass did not swap the arm64 -dev
packages for native ones.
This commit is contained in:
2026-09-15 18:05:57 +02:00
parent 5500f98586
commit b34e86dcfe
2 changed files with 148 additions and 16 deletions
+29 -16
View File
@@ -276,26 +276,39 @@ pub async fn build(
return Err("Could not install build-dependencies for the build".into());
}
// Install arch-independant build dependencies
log::debug!("Installing arch-independant build dependencies...");
let status = cap(
ctx.command("apt-get")
.current_dir(package_dir_str)
// Install arch-independant build dependencies, only if the source declares
// any: without --arch-only this pass resolves the whole Build-Depends field
// too, which is redundant after the first pass and breaks cross builds.
let has_indep_deps = match ctx.read_file(&package_dir.join("debian/control")) {
Ok(control) => control
.lines()
.any(|l| l.to_ascii_lowercase().starts_with("build-depends-indep:")),
Err(e) => {
log::debug!("cannot read debian/control for indep build-deps: {}", e);
true
}
};
if has_indep_deps {
log::debug!("Installing arch-independant build dependencies...");
let mut cmd = ctx.command("apt-get");
cmd.current_dir(package_dir_str)
.envs(env.clone())
.arg("-y")
.arg("build-dep")
.arg("./"),
&sink,
)
.status()?;
.arg("build-dep");
if cross {
cmd.arg(format!("--host-architecture={arch}"));
}
cmd.arg("./");
let status = cap(&mut cmd, &sink).status()?;
// If build-dep fails, we try to explain the failure using dose-debcheck
if !status.success() {
if let Some(u) = &ui {
u.suspend();
// If build-dep fails, we try to explain the failure using dose-debcheck
if !status.success() {
if let Some(u) = &ui {
u.suspend();
}
dose3_explain_dependencies(package, version, arch, build_root, cross, ctx.clone())?;
return Err("Could not install build-dependencies for the build".into());
}
dose3_explain_dependencies(package, version, arch, build_root, cross, ctx.clone())?;
return Err("Could not install build-dependencies for the build".into());
}
// Run the build step