On Fri, 17 May 2024 at 08:14:41 +0200, Helmut Grohne wrote:
> Package: libglib2.0-dev
> Version: 2.80.2-1
> User: debian-cr...@lists.debian.org
> Usertags: ftcbfs
> Control: affects -1 + src:tkgate
> X-Debbugs-Cc: debian-cr...@lists.debian.org
> 
> you recently added an alternative python3 to the qemu dependency. This
> is posing a challenge to cross building now, but the devil is in the
> detail.

This is happening because upstream GLib 2.80.x has taken over
the lower-level parts of the GObject-Introspection toolchain
from src:gobject-introspection. As a result, providing its full
functionality requires the ability to run host-architecture binaries
(for at least gi-compile-repository, which will eventually replace
gobject-introspection's g-ir-compiler).

In older versions, src:gobject-introspection would likely have had
the same issue; the only difference is that libglib2.0-dev affects
more packages.

As a reminder of the design here, g-ir-scanner from in the
gobject-introspection source package examines shared libraries and outputs
GIR XML, which is analogous to C headers: usually, but not always,
architecture-independent. g-ir-compiler or gi-compile-repository takes the
GIR XML and compiles it into architecture-dependent binary typelibs.
The GIR XML is used directly by some language bindings (typically at
compile-time for static languages like Rust and C++), and the typelibs are
used for others (typically at runtime for dynamic languages like Perl and
Paython).

I had initially hoped that we could wrap the build-architecture
g-ir-compiler/gi-compile-repository to compile GIR XML into typelibs,
but that was broken and caused a RC bug (#1066900), so we cannot do that.

In principle we could build one copy of gi-compile-repository per (build
architecture, host architecture) pair, like cross-compilers, but that
seems bad from a maintainabiity point of view. Upstream does not support
this use-case (and in general has little interest in cross g-i) so it
would be very easy for it to regress, it would require either GLib or
some other package to know a complete list of all interesting Debian
architectures in the same way that gcc-13-cross does, and running
g-ir-scanner fundamentally requires executing code from the host
architecture *anyway* because that's just how g-i works.

If the dependency was changed to:

    something-native | qemu-user | qemu-user-static,
    python3:any,

where "something-native" is any package that is either M-A: no or
M-A: allowed (but must not be M-A: foreign, and in practice is required
to be installed from a runnable architecture and not a barbarian
architecture) but is *not* Python, would that solve the problem?

Most of the obvious Essential or Build-Essential packages like base-files
are Multi-Arch: foreign, therefore not suitable for this purpose, but for
example a short-term hack version of this might be to use apt, perl or
perl-base as the something-native - because they are already installed
(and because apt is Important: yes and perl-base is Essential: yes),
hopefully apt will prefer to keep the existing version installed and take
the qemu-user alternative, in preference to attempting to crossgrade them
to a version that does not, in fact, work.

I don't know whether apt might become Multi-Arch: foreign in the future,
though. If it did, that would break our ability to use it like this.

This intersects with #1070773, in which users of amd64 + i386 multiarch
don't want to have to install qemu-user, and would prefer to have some
way to say "it's OK, my amd64 system can run i386 binaries directly".

If someone with more time available for cross-development
implemented the cross-exe-wrapper design that I sketched in
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1030223#37, then
gobject-introspection and libglib2.0-dev would be able to migrate to
depending on

    cross-exe-wrapper | can-run-arch,
    python3:any,

or for backwards-compat maybe

    cross-exe-wrapper | can-run-arch | qemu-user | qemu-user-static,
    python3:any,

and I think this would also solve the problem?

If that doesn't work, another option (but IMO a bad one) is that because
g-i functionality in GLib is a new feature in trixie, it would in
principle be possible to move gi-compile-repository and related tools to
a separate binary package, at the cost of breaking backwards compatibility
with older versions of trixie-as-testing (and also breaking compatibility
with Ubuntu 24.04, which would be unfortunate). We would probably need
*two* new binary packages:

- one Multi-Arch: same, analogous to gobject-introspection, to contain
  /usr/bin/$(DEB_HOST_GNU_ARCH)-gi-*, plus their implementations in a
  private directory (at the moment this is part of libglib2.0-dev);

- and one Multi-Arch: no containing the non-architecture-prefixed
  /usr/bin/gi-* which will be expected by simple non-cross-capable
  upstream scripts and build systems (at the moment this is part of
  libglib2.0-dev-bin, which is Multi-Arch: foreign, which is not 100%
  correct but is the best we can do to accommodate these naive build
  systems' expectations)

Hoever, I believe the package containing
/usr/bin/$(DEB_HOST_GNU_ARCH)-gi-* could cause the same installation
issue for your cross-build infrastructure that libglib2.0-dev now causes:
you'll see that gobject-introspection.deb also has this
"python3 | qemu-user, python3:any" dependency. So I'm not convinced that
would actually help, it would probably just move the problem around.

> On a technical level, python3 | qemu expresses what we want. The crossqa
> service sees this and has special handling for python3. It considers
> python3.*-minimal to not be installable for the host architecture (as
> that pratically fails postinst).
...
> and then apt looks at the dependencies. It sees python3 as the first
> alternative and is generally happy with installing the host one.

I think this is the real problem here. We say python3:any because that's
what the multiarch dependency syntax allows us to say, but what we
*mean* is "well *obviously* I need to be able to run the interpreter".
A better syntax, if it was allowed, would be python3:runnable or even
python3:native - but we can't say that in this context.

crossqa's dependency resolver has this special case to treat non-native
python3 as uninstallable, but apt does not, and it's that disagreement
that is breaking your test scenario.

> I note that this bug has a bit of urgency, because affected packages
> will be marked as bd-uninstallable and that is taken as a sign to stop
> trying to build the relevant architecture and makes crossqa.d.n stop
> doing builds until the next mirror push. So this bug breaks QA.

I'm sorry that GObject-Introspection is complicated, but that's just
the way it is. I am doing the best I can do make it work the way you
would want it to within my limited time and resources, and in some cases
against upstream hostility. If you would have preferred cross-g-i to
remain impossible, that would have been the other realistic option here.

I'm open to suggestions for how to resolve this, but I cannot always
drop everything to solve cross issues immediately, and I certainly
didn't intend to be Debian's single point of failure for all things
gobject-introspection.

    smcv

Reply via email to