Bug#1071246: libglib2.0-dev's python3 dependency alternative is posing challenges to cross building

Helmut Grohne helmut at subdivi.de
Wed Jul 31 16:17:29 BST 2024


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



More information about the pkg-gnome-maintainers mailing list