Subject: Re: bug#50201: [PATCH core-updates-frozen 0/52] Support cross-compilation in glib-or-gtk-build-system and fix cross-compilation errors

From: Maxime Devos <[email-masked]>
Date: Mon, 30 Aug 2021 18:45:48 +0200

Mathieu Othacehe schreef op ma 30-08-2021 om 15:00 [+0200]:
> Hey,
> 
> > +               ;; introspection requires running binaries for the host system
> > +               ;; on the build system.
> > +               '("-Dintrospection=false"))
> 
> Nix is often ahead of Guix regarding cross-compilation support. Did you
> have a chance to see how they are dealing with introspection in the
> context of cross-compilation?

It appears that, say, atk can be cross-compiled on Nix, but other than that,
Nix doesn't seem to be ahead here.  We seem to be in good company here.  I found
the following

Nix setting -Dintrospection=false too when cross-compiling:
https://github.com/NixOS/nixpkgs/issues/72868

Nix people finding gobject-introspection is hard to cross-compile
https://github.com/NixOS/nixpkgs/issues?q=is%3Aissue+is%3Aopen+introspection

Nix people using an emulator (presumably QEMU?):
https://github.com/NixOS/nixpkgs/pull/88222/files

Unfortunately, it appears that introspection data is architecture-dependent:
<https://archive.md/U8rm2>, so just copying over the data from a natively
compiled version won't work (*).

One ‘solution’ is to run g-ir-scanner under QEMU:
<https://maxice8.github.io/8-cross-the-gir/>.  That isn't really cross-compilation
though, but emulated compilation, so it won't work with the Hurd.
Might be good enough for cross-compiling between Linux targets though ...

Here is an alternative idea that I won't attempt in this patch series:

(*) One solution would be to copy it over anyway and substitute things(***) where needed,
    and re-generate the typelib data.  That seems rather prone to mistakes though,
    so maybe we should then hash the adjusted introspection data and compare the hash
    to the hash of what we now the introspection data must be (**).

    Of course, we can't just guess that, so maybe when compiling atk natively for,
    say, x86_64-linux, a message

    ‘new introspection hashes: ("x86_64-linux-gnu" ("Atk-1.0" "THE-HASH"))’
    or
    ‘stale introspection hash: "Atk-1.0" "THE-OLD-HASH" "THE-NEW-HASH"

    followed by:

    ‘Please add it to #:gir-hashes to help cross-compilers.’

    could be printed (maybe even fail the build?).

    This hash checking and substitution could be implemented with an additional
    build phase for meson-build-system (#:gir would be an additional argument for
    meson-build-system).

    Something like:

    (package
      (name "atk")
      [...]
      (arguments
        `(#:gir-hashes
          (("x86_64-linux-gnu" ("Atk-1.0" "THE-HASH"))
           ("powerpc64-linux-gnu"
            ("Atk-1.0"
             ;; XXX(core-updates): We forgot to update the hash,
             ;; and now we're stuck with it unless we want a world-rebuild
             ;; for powerpc64le-linux (other architectures would be unaffected).
             ;; Use the right hash when cross-compiling.
             ,(if (%current-target-system)
                  "THE-CORRECT-HASH"
                  "THE-OLD-HASH"))
           ;; XXX I forgot the triplet, imagine you saw the triplet here instead ...
           ("i586-hurd" ...)
           ...)
          #:gir-substitutions
          ;; TODO: need to thing of a good scheme here ...
          ((replace-value c:identifier "ARCHITECTURE_DEPENDENT"
            ((? architecture "ppc64le") "x")
            ((? ...) "y"))
           (replace-value c:identifier "KERNEL_DEPENDENT"
            ((? kernel-os "linux-gnu") "x")
            ((? kernel-os "gnu") "y"))
           ;; Only x86_64 has this quirk.
           (replace-value c:identifier "QUIRK"
            ((? architecture "x86_64") "yes)
            (otherwise "no"))))
     [...])

    A limitation of this solution is that someone needs to compile it natively
    for the target architecture first (possibly emulated with QEMU).

(**) The .gir includes the name of the shared library, so maybe compute the hash
     modulo store references to avoid invalidating the reference hashes every time
     an (indirect) dependency is updated.

(***) An ordinary 'substitute*' won't work well, something specific for .gir XML
      would be needed.  E.g., consider the following (in this case architecture-independent)
      snippet from Atk-1.0.gir:

      <member name="alert"
              value="2"
              c:identifier="ATK_ROLE_ALERT"
              glib:nick="alert">
        <doc xml:space="preserve"
             filename="../atk/atkobject.h"
             line="39">An object which is an alert to the user. Assistive Technologies typically respond to ATK_ROLE_ALERT by reading the entire onscreen co>
      </member>

      Sometimes the ‘value="..."’ part is architecture-dependent, and needs to
      be adjusted for the target architecture.

Greetings,
Maxime.