Hi Simon, I'm sorry for having expressed urgency and then dropped the ball myself. As it stands, this still breaks crossqa.debian.net, but we're so understaffed that nobody was available to improve the situation thus far.
On Tue, May 21, 2024 at 11:00:18AM +0100, Simon McVittie wrote: > Thinking more about this, though, I think the cross-exe-wrapper itself > could have the same problem that you've described in libglib2.0-dev: > on build=amd64 and (let's say) host=riscv64, if we had something like > > Package: libglib2.0-dev > Architecture: riscv64 > Multi-Arch: same > Depends: cross-exe-wrapper | can-run > > Package: cross-exe-wrapper > Architecture: riscv64 > Multi-Arch: same > Depends: cross-exe-wrapper-riscv64-linux-gnu > > Package: cross-exe-wrapper-riscv64-linux-gnu > Architecture: riscv64 > Multi-Arch: ??? # no? foreign? allowed? > # trivial wrapper, runs binary directly > > Package: cross-exe-wrapper-riscv64-linux-gnu > Architecture: amd64 > Multi-Arch: foreign > Depends: qemu-user > # non-trivial wrapper, runs via qemu I think this approach can be implemented on a technical level. Package: native-architecture Architecture: all Multi-Arch: no # empty package # do something about the multiarch hinter to make it stop suggest adding # M-A:foreign Package: cross-exe-wrapper Architecture: any Multi-Arch: same Depends: native-architecture | qemu-user, native-architecture | arch-test # wrapper below #Package: cross-exe-wrapper-$triplet # deleted, not necessary Say we're satisfying a dependency on libglib2.0-dev for some architecture $host_arch. Doing so will cause apt to install cross-exe-wrapper:$host_arch (as M-A:same forwards the architecture constraint). apt will then attempt to install native-architecture for $host_arch. That is possible if $host_arch happens to be the native architecture (i.e. if dpkg happens to be $host_arch) and apt will favour this solution when available. When $host_arch is non-native, the first alternative will be unsatisfiable and apt will resort to the second one. The actual wrapper script's name should be architecture-dependent such as $host_triplet-cross-exe-wrapper. It can roughly look like: #!/bin/sh if test "$(dpkg --print-architecture)" = #DEB_HOST_ARCH# || arch-test -n #DEB_HOST_ARCH# >/dev/null; then exec "$@" else exec qemu-#DEB_HOST_ARCH# -- "$@" fi I have not actually attempted running this yet, so there still is a chance of me getting a key aspect wrong, but this looks to me like it should be possible to make it work technically. Let me note that I have been arguing in favour of changing the semantics or Arch:all in ways that would break the aforementioned setup. Roughly speaking, I suggest that Arch:all packages should not implicitly behave as native architecture packages, but can be configured for any architecture. As such the dpkg database would then have to track the actual architecture for all Arch:all packages. A consequence of this would also be that the dependencies of Arch:all packages would be resolved according to the chosen architecture rather than the native one. In practice, apt would rarely choose an architecture different from the native one. In a cross build environment, this would enable us to package header-only libraries (such as all of rust) as Arch:all packages. You don't have to understand the details of this, but the takeaway is that I would like to break the semantics that make your proposal work. While I indicated that the barbarian approach would not cover all cases earlier, I was unable to reproduce such a case more recently and failed to record what cases failed earlier. I recently encountered the following packages that would fail to install their Build-Depends due to choosing a host architecture Python interpreter and failing its postinst: * atop * bemenu * cairomm1.16 * converseen * cups-filters * darktable * dmtx-utils * fastfetch * freefilesync * frei0r * group-service * gsmartcontrol * gstreamer-vaapi * gst-rtsp-server1.0 FTCBFS #1060838 * imview * kylin-scanner * lbreakouthd * mate-user-admin * mixxx * mpv-mpris * nvidia-vaapi-driver * otpclient * povray * pqiv * qimgv * sayonara * siril * swayimg * wmaker I verified that all of these packages (but one) cross build successfully for arm64 on amd64 when marking arm64 as barbarian by adding --chroot-setup-commands='echo "APT::BarbarianArchitectures {\"arm64\"};" > /etc/apt/apt.conf.d/barbarian.conf' to the sbuild invocation. This gives rise to the question of which of the available solutions should be preferred (or whether we want to use both of them at the same time). There are two main downsides of going forward with barbarian as far as I can see. One is that we restrict the solution space and outright reject ever installing a host's instance of a M-A:foreign package in a cross build environment. I don't know why that would ever be necessary, but then we can no longer do it. The other is that we need to fix all the builders to make cross building unstable work. In particular, bookworm's sbuild will no longer be able to cross build unstable. My current thinking is that both of these downsides are ok-ish given the benefits we get in return. I'd appreciate getting more opinions on this especially from Simon and Johannes, but also others such that we can move forward in a consensus-driven way. Helmut