Crossing the gir
Introduction
For those uninitiated, gir is GObject Introspection. A technology from GNOME that allows libraries to expose bindings to any language that can speak to C. It is the reason you can use lots of languages to write your GNOME and GTK applications while Qt5 is mostly limited to C++ and Python.
On Void Linux a high emphasis is placed into stuff being able to be cross compiled and for a long time gir has eluded us, with it's requirement of running stuff on the target system and using raw dumps of C structures.
Now this is a river that is going to be crossed.
crossing the gir
Artifact means any piece of compiled code
Making gir cross compilable is not an easy task, as described above it requires running artifacts created for the target system, the bane of cross compilation.
Most of the time when running artifacts for a package it means generators, which can most of the time be built on the host system and then ran just fine.
Not for gir, it needs specific information from those artifacts that is only pertinent to the target architecture.
gobject-introspection
We start with the beast itself, a collection of tools for generate .gir
and
.typelib
files, g-ir-scanner
, g-ir-compiler
, g-ir-generate
. Also a
collection of common bindings like DBus
, GLib
, etc.
Thankfully for us, the Yocto Project and
Buildroot did all of the work patching gir, most
of the work required was importing the required parts, discarding what we
don't use and gluing it in xbps-src's
infrastructure.
prelink-cross
One of the first things required was importing a tool that the Yocto Project used on their gir works.
It was easy enough for glibc
systems, while we had to fetch a git commit
there wasn't much problem getting it compile and run with success.
The problem came when musl
appeared, Void Linux
developer Enno "Gottox" Boland tackled this
problem, and at every corner compatibility problems appeared. Nonetheless
he did it, and made prelink-cross
available for use in Void Linux
# Template file for 'prelink-cross' pkgname=prelink-cross version=20180128 revision=1 _githash=ca213abd9ebfd77a04e3a967bf9f7bc1ef832087 wrksrc="prelink-cross-${_githash}" build_style=gnu-configure hostmakedepends="automake libtool" makedepends="elfutils-devel binutils-devel" case $XBPS_TARGET_MACHINE in *-musl) makedepends+=" argp-standalone"; LDFLAGS+=" -largp" ;; esac short_desc="Prelink from the yocto project" maintainer="maxice8 <thinkabit.ukim@gmail.com>" license="GPL-2.0-or-later" homepage="https://git.yoctoproject.org/cgit.cgi/prelink-cross" distfiles="https://github.com/Gottox/prelink-cross/archive/$_githash.tar.gz" checksum=b6b0baf60e7e66f62ed8e7117973be24b2d24649490365e6a88e11be0dd2fab4 pre_configure() { autoreconf -fi } post_install() { # We don't want the tools that are on prelink # just prelink-rltd rm -f ${DESTDIR}/usr/bin/{execstack,prelink} rm -rf ${DESTDIR}/usr/share/man }
To have an idea of the patching required, this is the git additions/deletions
of all changes made, to work around glibc
specific behaviour:
configure.ac | 1 + gelfx32/gelfx.h | 2 +- src/Makefile.am | 2 +- src/arch-alpha.c | 2 +- src/arch-arm.c | 2 +- src/arch-cris.c | 2 +- src/arch-i386.c | 2 +- src/arch-ia64.c | 2 +- src/arch-mips.c | 2 +- src/arch-ppc.c | 2 +- src/arch-ppc64.c | 2 +- src/arch-s390.c | 2 +- src/arch-s390x.c | 2 +- src/arch-sh.c | 2 +- src/arch-sparc.c | 2 +- src/arch-sparc64.c | 2 +- src/arch-x86_64.c | 2 +- src/cache.c | 2 +- src/checksum.c | 2 +- src/conflict.c | 2 +- src/cxx.c | 2 +- src/doit.c | 2 +- src/dso.c | 2 +- src/dwarf2.c | 2 +- src/elf.h | 4 ---- src/exec.c | 2 +- src/execle_open.c | 2 +- src/execstack.c | 2 +- src/fptr.c | 2 +- src/gather.c | 6 +++++- src/get.c | 2 +- src/layout.c | 2 +- src/main.c | 4 ++-- src/md5.h | 8 ++++---- src/mdebug.c | 2 +- src/prelink.c | 2 +- src/reloc.c | 2 +- src/rtld/Makefile.am | 1 + src/rtld/dl-load.c | 2 +- src/rtld/dl-lookup.c | 2 +- src/rtld/dl-misc.c | 2 +- src/rtld/dl-object.c | 2 +- src/rtld/dl-version.c | 4 ++-- src/rtld/rtld.c | 6 +++--- src/rtld/rtld.h | 2 +- src/space.c | 2 +- src/stabs.c | 2 +- src/undo.c | 2 +- src/undoall.c | 2 +- src/verify.c | 11 +++++++++- src/wrap-error.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/wrap-error.h | 11 ++++++++++ src/wrap-file.c | 8 ++++---- 53 files changed, 140 insertions(+), 62 deletions(-)
Regardless, with that out of the way we can go back to gir.
wrapping gobject-introspection
We can now make use of the patches from the Yocto Project, and we need to write our own wrappers based on Yocto's ones.
First we need to wrap g-ir-scanner
, easy enough we renamed the executable
that is built by the package to g-ir-scanner.wrapped
and claim
g-ir-scanner
for ourselves with this:
#!/usr/bin/env bash # Check if we are running in an xbps-src environment and run the wrapper if that # is the case. if [ -n "$XBPS_CROSS_BASE" -a -n "$XBPS_TARGET_MACHINE" -a -n "$XBPS_VERSION" ]; then # This prevents g-ir-scanner from writing cache data to $HOME export GI_SCANNER_DISABLE_CACHE=1 exec /usr/bin/g-ir-scanner.wrapped \ --use-binary-wrapper=/usr/bin/g-ir-scanner-qemuwrapper \ --use-ldd-wrapper=/usr/bin/g-ir-scanner-lddwrapper \ --add-include-path=${XBPS_CROSS_BASE}/usr/share/gir-1.0 \ --add-include-path=${XBPS_CROSS_BASE}/usr/lib/gir-1.0 \ "${@//-I\/usr\/include/-I${XBPS_CROSS_BASE}\/usr\/include}" fi exec /usr/bin/g-ir-scanner.wrapped "$@"
You may notice the --use-binary-wrapper=
and --use-ldd-wrapper=
,
which point to other wrappers we also need to write, again based on Yocto's
but for Void Linux specifically.
Here is g-ir-scanner-qemuwrapper
:
#!/bin/sh # Use a modules directory which doesn't exist so we don't load random things # which may then get deleted (or their dependencies) and potentially segfault export GIO_MODULE_DIR=${XBPS_CROSS_BASE}/gio/modules-dummy case "$XBPS_TARGET_MACHINE" in x86_64*) _MACHINE=x86_64 ;; i686) _MACHINE=i386 ;; aarch64*) _MACHINE=aarch64 ;; armv*) _MACHINE=arm ;; esac /usr/bin/qemu-${_MACHINE}-static \ -L ${XBPS_CROSS_BASE} \ -E LD_LIBRARY_PATH="${XBPS_CROSS_BASE}/usr/lib:.libs:${GIR_EXTRA_LIBS_PATH}" \ "$@"
You may notice we make use of qemu-user-static
to run on the target machine.
And g-ir-scanner-lddwrapper
, this is where prelink-cross
appears:
#!/bin/sh /usr/bin/prelink-rtld --root=${XBPS_CROSS_BASE} "$@"
That wraps ups our wrapper for g-ir-scanner
, now we need to wrap g-ir-compiler
.
This one gets more complicated as we need to wrap it in a way it can know
to use the g-ir-compiler
from the gir if it's being currently built.
#!/bin/sh # # Check if we are running in an xbps-src environment and run the wrapper if that # is the case. if [ -n "$XBPS_CROSS_BASE" -a -n "$XBPS_TARGET_MACHINE" -a -n "$XBPS_VERSION" ]; then # wrapper for g-ir-compiler, which runs the target version of it through qemu. # g-ir-compiler writes out the raw content of a C struct to disk, and therefore # is architecture dependent. if [ -x build/tools/g-ir-compiler ]; then # We are compiling gobject-introspection. # lets used the one we just compiled. gir_bin=build/tools/g-ir-compiler elif [ -x ${XBPS_CROSS_BASE}/usr/bin/g-ir-compiler.wrapped ]; then # Lets use the g-ir-compiler from the target gir_bin=${XBPS_CROSS_BASE}/usr/bin/g-ir-compiler.wrapped fi exec /usr/bin/g-ir-scanner-qemuwrapper ${gir_bin} "$@" fi exec /usr/bin/g-ir-compiler.wrapped "$@"
OK, the wrappers are wrapped, let's make the template install them correctly.
$ sed -n '29,43p' srcpkgs/gobject-introspection/template # Install our wrappers system-wide, they are required for building all other # gobject-based packages. vbin ${FILESDIR}/g-ir-scanner-qemuwrapper vbin ${FILESDIR}/g-ir-scanner-lddwrapper # Install g-ir-scanner-wrapper as g-ir-scanner, we need it with that name since # we can't expect people to just not hardcode /usr/bin/g-ir-scanner, some packages # like gtk+3 just like **really** much to use /usr/bin/g-ir-scanner and meson with # find_program is also to blame. mv ${DESTDIR}/usr/bin/g-ir-scanner{,.wrapped} vbin ${FILESDIR}/g-ir-scanner-wrapper g-ir-scanner # Same logic of g-ir-scanner applies here mv ${DESTDIR}/usr/bin/g-ir-compiler{,.wrapped} vbin ${FILESDIR}/g-ir-compiler-wrapper g-ir-compiler
Let's also allow our package to be cross compiled by setting the appropriate dependencies and configuration options for it.
$ sed -n '20,26p' srcpkgs/gobject-introspection/template if [ "$CROSS_BUILD" ]; then hostmakedepends+=" gobject-introspection qemu-user-static prelink-cross" configure_args+=" -Denable-host-gi=true -Denable-gi-cross-wrapper=/usr/bin/g-ir-scanner-qemuwrapper -Denable-gi-ldd-wrapper=/usr/bin/g-ir-scanner-lddwrapper -Dpkgconfig-sysroot-path=${XBPS_CROSS_BASE}" fi
pkg-config sysroot dir
Before finishing gir we need to do some final touches on its
pkg-config
files, which contains some very important variables
that packages use like g_ir_scanner
which points to the point
of the g-ir-scanner
binary and typelibdir
and girdir
which
point to the directory where the .typelib
and .gir
files are
to be found.
Packages query for these variables with pkg-config --variable <variable>
,
and a problem occurs there when cross compiling.
pkg-config
can normally be made to return values for the target
system by setting the PKG_CONFIG_SYSROOT_DIR
variable, when a
package queries for CFLAGS
with pkg-config --cflags
the
values returned for the includes (-I) are prefixed with the value
of PKG_CONFIG_SYSROOT_DIR
.
But, that doesn't happen for values queried with pkg-config --variable
,
if a package ask for where the .typelib
and .gir
files are, the values
returned are from the host system, not the target one.
Do not despair, not all is lost, we can prefix ${pc_sysrootdir}
in the
pkg-config
files and the value will be inserted as expected, so let's
do it in the template:
$ sed -n '45,54p' srcpkgs/gobject-introspection/template # modify the pkg-config files to respect ${pc_sysrootdir} for variables that are # meant to be called with 'pkg-config --variable' vsed -e 's|^g_ir_scanner=.*|g_ir_scanner=${pc_sysrootdir}/${bindir}/g-ir-scanner|g' \ -e 's|^g_ir_compiler=.*|g_ir_compiler=${pc_sysrootdir}/${bindir}/g-ir-compiler|g' \ -e 's|^g_ir_generate=.*|g_ir_generate=${pc_sysrootdir}/${bindir}/g-ir-generate|g' \ -e 's|^gidatadir.*|gidatadir=${pc_sysrootdir}/${datadir}/gobject-introspection-1.0|g' \ -e 's|^girdir.*|girdir=${pc_sysrootdir}/${datadir}/gir-1.0|g' \ -e 's|^typelibdir.*|typelibdir=${pc_sysrootdir}/${libdir}/girepository-1.0|g' \ -i ${DESTDIR}/usr/lib/pkgconfig/gobject-introspection-1.0.pc \ -i ${DESTDIR}/usr/lib/pkgconfig/gobject-introspection-no-export-1.0.pc
One last thing before we finish the gobject-introspection
package itself, let's
remove the EXT_SUFFIX
from the cpython3
bindings, so that cross compilation
is not affected by usage of the EXT_SUFFIX
from the host system and not the
target one, Reading this article is recommended
for further information.
$ sed -n '56,58p' srcpkgs/gobject-introspection/template # Fix the name of the python3 c bindings mv ${DESTDIR}/usr/lib/gobject-introspection/giscanner/_giscanner*.so \ ${DESTDIR}/usr/lib/gobject-introspection/giscanner/_giscanner.so
Let's try and compile it!
$ xbps-src -f -a aarch64 pkg gobject-introspection => Registering new packages to /host/binpkgs/gobject-introspection index: added `gir-freedesktop-1.58.3_2' (aarch64). index: added `gobject-introspection-1.58.3_2' (aarch64). index: added `libgirepository-1.58.3_2' (aarch64). index: added `libgirepository-devel-1.58.3_2' (aarch64). index: 8 packages registered.
Appears to work, let's spin up an aarch64
machine:
Thanks to Cogitri for lending the machine.
$ uname -m aarch64 $ python3 >>> import platform >>> platform.platform() 'Linux-4.14.91_1-aarch64-with-glibc2.17' >>> import gi >>> gi.require_version("DBus", "1.0") >>>
gir build_helper
We can now glue some components from xbps-src
to make cross compilation
of packages that use gir more convenient.
This time we will use the newly introduced build_helper
which, if you
haven't heard of them then this article is
recommended, here will be written only a very short explanation.
In short build_helper
is a system of files that contain shell snippets
that set global variables and template specific variables (like
hostmakedepends
) when sourced, they are a nice way to encapsulate
complex logic in a way that we can import them only when necessary.
Here is the new build_helper
for helping with gir cross compilation:
gir!
$ cat common/build-helper/gir.sh # # gir - build-helper for gobject-introspection # # This build-helper is used for packages that make use of # the GObject introspection middleware layer. # # Check if the 'gir' build_option is set or if there is no # 'gir' build_option. if [ "$build_option_gir" ] || [[ $build_options != *"gir"* ]]; then # Provide the host tooling, g-ir-scanner, g-ir-compiler and its # wrappers. hostmakedepends+=" gobject-introspection" if [ "$CROSS_BUILD" ]; then # Required for running binaries produced from g-ir-compiler # via g-ir-scanner-qemuwrapper hostmakedepends+=" qemu-user-static" # Required for running the g-ir-scanner-lddwrapper hostmakedepends+=" prelink-cross" # Provide basic .gir types like GLib, GObject, DBus, Gio, cairo # and tooling like g-ir-compiler makedepends+=" gobject-introspection" fi fi
python-gobject
Now that we got that nice glue, let's make use of it and start by
adapting python-gobject
to be cross compilable.
Why ? Everyone uses it, here is a list of the packages that depend
on either python-gobject
or python3-gobject
TwitchNotifier-0.5_1 avahi-discover-0.7_6 blueman-2.0.8_1 caffeine-ng-3.4.2_1 caribou-0.4.21_1 catfish-1.4.7_1 ccsm-0.8.16_4 cdemu-client-3.2.0_2 chrome-gnome-shell-10.1_1 cinnamon-4.0.9_1 cinnamon-screensaver-4.0.3_1 clearine-0.5_1 d-feet-0.3.14_1 devedeng-4.13.0_1 eolie-0.9.51_1 flowblade-1.16_2 gajim-1.1.2_1 gcdemu-3.2.0_1 gnome-3.30.0_3 gnome-music-3.30.2_1 gnome-passwordsafe-3.31.1_2 gnome-tweaks-3.30.2_1 gpodder-3.10.7_1 gpsd-xgps-3.17_4 gramps-5.0.1_1 gscreenshot-2.10.1_1 gst1-python-1.14.4_1 gst1-python3-1.14.4_2 guake-3.4.0_2 gufw-18.10.0_1 ibus-1.5.19_2 ibus-hangul-1.5.1_3 ice-ssb-5.3.4_1 indicator-doom-cpu-1.0.1_1 kupfer-319_2 laditools-1.1.0_2 libgladeui3-3.22.1_1 libpeas-1.22.0_1 libratbag-0.9.904_1 lightdm-gtk-greeter-settings-1.2.2_1 lollypop-0.9.916_1 lutris-0.4.23_1 mate-menu-18.04.3_1 mate-tweak-18.10.2_1 meld-3.20.0_1 menulibre-2.2.0_1 mkchromecast-0.3.8.1_1 mozo-1.20.2_1 mugshot-0.4.1_1 mypaint-1.2.1_5 networkmanager-dmenu-1.1_1 onboard-1.4.1_4 oomox-1.6.2_2 piper-0.2.903_1 pithos-1.4.1_1 pulseaudio-equalizer-ladspa-3.0.1_1 pulseeffects-3.2.3_3 pychess-0.12.4_2 python-atspi-2.30.0_1 python-gobject-devel-3.30.4_2 python3-atspi-2.30.0_1 python3-dbusmock-0.18.1_1 python3-openrazer-2.4.0_1 quodlibet-4.2.1_2 rednotebook-2.8_1 redshift-gtk-1.12_1 sc-controller-0.4.6.1_1 scanmem-0.17_4 sonata-1.7b1_2 soundconverter-3.0.0_3 startup-tools-1.13.4_1 syncthing-gtk-0.9.4.3_1 system-config-printer-1.5.11_4 terminator-1.91_1 tryton-5.0.5_1 uberwriter-12.11.02_1 udiskie-1.7.5_1 variety-0.7.1_1 vimiv-0.9.1_2 virt-manager-tools-2.0.0_2 volctl-0.6.2_1 wpgtk-5.8.7_1 xdot-1.0_1 zeitgeist-1.0.1_1
Quite a lot, eh ?
Here is the python3-gobject
template, notable is the usage of the gir
build_helper.
# Template file for 'python3-gobject' pkgname=python3-gobject version=3.30.4 revision=1 wrksrc="pygobject-${version}" build_style=meson build_helper="gir" configure_args="-Dpython=python${py3_ver}" pycompile_module="gi pygtkcompat" hostmakedepends="pkg-config" makedepends="libglib-devel python3-cairo-devel python3-devel" depends="gir-freedesktop python3-cairo" short_desc="Python3 bindings for GObject" maintainer="Enno Boland <gottox@voidlinux.org>" license="LGPL-2.1-or-later" homepage="https://pygobject.readthedocs.io/" distfiles="${GNOME_SITE}/pygobject/${version%.*}/pygobject-${version}.tar.xz" checksum=2dc1a1a444b82955e65b81c2a2511ecf8032404beba4ef1d48144168f2f64c43 case "$XBPS_TARGET_MACHINE" in x86_64-musl) ;; *-musl) broken="Error relocating /usr/aarch64-linux-musl/usr/lib/libz.so.1: unsupported relocation type 1026" ;; esac python3-gobject-devel_package() { depends="libgirepository-devel python3-cairo-devel libglib-devel libffi-devel python3-gobject>=${version}_${revision}" short_desc+=" - development files" pkg_install() { vmove usr/include vmove usr/lib/pkgconfig } }
Before we can have some fun with it and compile some base software we need
to deal with one last issue, meson
.
meson
The meson implementation of gir generation unconditionally uses the native
pkg-config
, it makes sense since nobody (except Yocto, and now us) does
cross gir.
Using the native pkg-config
means it will run /usr/bin/pkg-config
and
thus will only search parts of the host system and not of the cross system,
which is great when we need to build generators
and other binaries that
run on the host system to help the build process, but in this case we
need the information from the target system.
Let's just patch the meson
package to do it. It is a one line change.
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index bf49770..42473cb 100644 --- mesonbuild/modules/gnome.py +++ mesonbuild/modules/gnome.py @@ -429,7 +429,7 @@ class GnomeModule(ExtensionModule): try: gir_dep = self.gir_dep or PkgConfigDependency('gobject-introspection-1.0', state.environment, - {'native': True}) + {'native': False}) pkgargs = gir_dep.get_compile_args() except Exception: raise MesonException('gobject-introspection dependency was not found, gir cannot be generated.')
OK, all done!
Let's have fun!
Let's have some fun!, let's cross compile gtk+3
with gir!
dep: gdk-pixbuf
First we need to build the dependencies of gtk+3
that it uses
for building its own gir files.
diff --git a/srcpkgs/gdk-pixbuf/template b/srcpkgs/gdk-pixbuf/template index d8c2c6db67..e353c55197 100644 --- a/srcpkgs/gdk-pixbuf/template +++ b/srcpkgs/gdk-pixbuf/template @@ -3,10 +3,10 @@ pkgname=gdk-pixbuf version=2.38.0 revision=1 build_style=meson +build_helper="gir" configure_args="-Dgir=$(vopt_if gir true false) -Djasper=false -Dpng=true -Dx11=true -Dinstalled_tests=false" -hostmakedepends="gettext-devel glib-devel pkg-config - $(vopt_if gir 'gobject-introspection') libxslt docbook-xsl" +hostmakedepends="gettext-devel glib-devel pkg-config libxslt docbook-xsl" makedepends="libX11-devel libglib-devel libpng-devel tiff-devel shared-mime-info" short_desc="Image loading library for The GTK+ toolkit (v2)" @@ -18,12 +18,11 @@ checksum=dd50973c7757bcde15de6bcd3a6d462a445efd552604ae6435a0532fbbadae47 # Package build options build_options="gir" +build_options_default="gir" # Disable gir for cross builds. if [ "$CROSS_BUILD" ]; then hostmakedepends+=" gdk-pixbuf-devel" -else - build_options_default="gir" fi pre_configure() {
Now let's build it and check the contents.
$ xbps-src -f -a aarch64 pkg gdk-pixbuf => Registering new packages to /host/binpkgs/gobject-introspection index: added `gdk-pixbuf-2.38.0_1' (aarch64). index: added `gdk-pixbuf-devel-2.38.0_1' (aarch64). index: added `gdk-pixbuf-xlib-2.38.0_1' (aarch64). index: 11 packages registered. $ env XBPS_TARGET_ARCH=aarch64 xls gdk-pixbuf{,-devel} | grep -E '.(gir|typelib)' /usr/lib/girepository-1.0/GdkPixbuf-2.0.typelib /usr/lib/girepository-1.0/GdkPixdata-2.0.typelib /usr/share/gir-1.0/GdkPixbuf-2.0.gir /usr/share/gir-1.0/GdkPixdata-2.0.gir
dep: pango
Same thing for pango
:
diff --git a/srcpkgs/pango/template b/srcpkgs/pango/template index 2ba99274b5..98adbd8f1d 100644 --- a/srcpkgs/pango/template +++ b/srcpkgs/pango/template @@ -4,8 +4,8 @@ version=1.42.4 revision=1 configure_args="$(vopt_enable gir introspection) --disable-gtk-doc" build_style=gnu-configure # switch to meson when possible -hostmakedepends="glib-devel help2man pkg-config - $(vopt_if gir 'gobject-introspection')" +build_helper="gir" +hostmakedepends="glib-devel help2man pkg-config" makedepends="fribidi-devel harfbuzz-devel libXft-devel libthai-devel" short_desc="Library for layout and rendering of text" maintainer="Juan RP <xtraeme@voidlinux.org>" @@ -16,10 +16,7 @@ checksum=1d2b74cd63e8bd41961f2f8d952355aa0f9be6002b52c8aa7699d9f5da597c9d # Package build options build_options="gir" -# Disable gir for cross builds. -if [ -z "$CROSS_BUILD" ]; then - build_options_default="gir" -fi +build_options_default="gir" post_install() { rm -rf -- "${DESTDIR}"/usr/share/installed-tests
Build and list gir files:
$ xbps-src -f -a aarch64 pkg pango => Registering new packages to /host/binpkgs/gobject-introspection index: added `pango-1.42.4_1' (aarch64). index: added `pango-devel-1.42.4_1' (aarch64). index: added `pango-view-1.42.4_1' (aarch64). index: added `pango-xft-1.42.4_1' (aarch64). index: 15 packages registered. $ env XBPS_TARGET_ARCH=aarch64 xls pango{,-devel} | grep -E '.(gir|typelib)' /usr/lib/girepository-1.0/Pango-1.0.typelib /usr/lib/girepository-1.0/PangoCairo-1.0.typelib /usr/lib/girepository-1.0/PangoFT2-1.0.typelib /usr/share/gir-1.0/Pango-1.0.gir /usr/share/gir-1.0/PangoCairo-1.0.gir /usr/share/gir-1.0/PangoFT2-1.0.gir /usr/share/gir-1.0/PangoXft-1.0.gir
dep: atk
Last one required!
diff --git a/srcpkgs/atk/template b/srcpkgs/atk/template index 7cb2c212cb..2531e3e127 100644 --- a/srcpkgs/atk/template +++ b/srcpkgs/atk/template @@ -3,8 +3,9 @@ pkgname=atk version=2.30.0 revision=1 build_style=meson +build_helper="gir" configure_args="-Dintrospection=$(vopt_if gir true false)" -hostmakedepends="pkg-config glib-devel $(vopt_if gir gobject-introspection)" +hostmakedepends="pkg-config glib-devel" makedepends="libglib-devel" short_desc="Set of interfaces for accessibility" maintainer="Juan RP <xtraeme@voidlinux.org>" @@ -15,11 +16,7 @@ checksum=dd4d90d4217f2a0c1fee708a555596c2c19d26fef0952e1ead1938ab632c027b # Package build options build_options="gir" - -# Disable gir for cross builds. -if [ -z "$CROSS_BUILD" ]; then - build_options_default="gir" -fi +build_options_default="gir" atk-devel_package() { depends="${makedepends} atk>=${version}_${revision}"
$ xbps-src -f -a aarch64 pkg atk => Registering new packages to /host/binpkgs/gobject-introspection index: added `atk-2.30.0_1' (aarch64). index: added `atk-devel-2.30.0_1' (aarch64). index: 17 packages registered. $ env XBPS_TARGET_ARCH=aarch64 xls pango{,-devel} | grep -E '.(gir|typelib)' /usr/lib/girepository-1.0/Atk-1.0.typelib /usr/share/gir-1.0/Atk-1.0.gir
All done, now for gtk+3
itself!
gtk+3
A very complex template, a maze of conditionals.
diff --git a/srcpkgs/gtk+3/template b/srcpkgs/gtk+3/template index 1a09502be3..b2315300d0 100644 --- a/srcpkgs/gtk+3/template +++ b/srcpkgs/gtk+3/template @@ -4,6 +4,7 @@ version=3.24.4 revision=1 wrksrc="gtk+-${version}" build_style=gnu-configure +build_helper="gir" #XXX broken configure script: Can't use vopt_enable cloudproviders, configure #checks for libcloudproviders when we pass '--disable-cloudproviders' to it! configure_args="--disable-schemas-compile @@ -12,9 +13,8 @@ configure_args="--disable-schemas-compile $(vopt_enable wayland wayland-backend) $(vopt_enable x11 x11-backend) $(vopt_if cloudproviders '--enable-cloudproviders')" conf_files="/etc/gtk-3.0/im-multipress.conf" -hostmakedepends="gettext-devel glib-devel gobject-introspection gtk-doc - gtk-update-icon-cache pkg-config perl - $(vopt_if wayland 'wayland-devel wayland-protocols')" +hostmakedepends="gettext-devel glib-devel pkg-config perl gtk-doc + gtk-update-icon-cache $(vopt_if wayland 'wayland-devel wayland-protocols')" makedepends="at-spi2-atk-devel gdk-pixbuf-devel libepoxy-devel pango-devel iso-codes $(vopt_if colord 'colord-devel') $(vopt_if cups 'cups-devel') $(vopt_if wayland 'libxkbcommon-devel wayland-devel wayland-protocols MesaLib-devel') @@ -35,12 +35,7 @@ desc_option_broadway="Enable support for the HTML5 Broadway backend" desc_option_cloudproviders="Enable integration with cloudproviders, such as Nextcloud" # Enable all options (other than cloudproviders) by default. -build_options_default="colord cups broadway wayland x11" - -# Enable gir only for native builds. -if [ -z "$CROSS_BUILD" ]; then - build_options_default+=" gir" -fi +build_options_default="colord cups broadway wayland x11 gir" do_check() { # Requires xserver running
Seems to be all right.
$ xbps-src -f -a aarch64 pkg gtk+3 => Registering new packages to /host/binpkgs/gobject-introspection index: added `gtk+3-3.24.4_1' (aarch64). index: added `gtk+3-demo-3.24.4_1' (aarch64). index: added `gtk+3-devel-3.24.4_1' (aarch64). index: 20 packages registered. $ env XBPS_TARGET_ARCH=aarch64 xls gtk+3{,-devel} | grep -E '.(gir|typelib)' /usr/lib/girepository-1.0/Gdk-3.0.typelib /usr/lib/girepository-1.0/GdkX11-3.0.typelib /usr/lib/girepository-1.0/Gtk-3.0.typelib /usr/share/gir-1.0/Gdk-3.0.gir /usr/share/gir-1.0/GdkX11-3.0.gir /usr/share/gir-1.0/Gtk-3.0.gir
Ah all nice.
$ python3 >>> import platform >>> platform.platform() 'Linux-4.14.97_1-aarch64-with-glibc2.17' >>> import gi >>> gi.require_version("Gtk", "3.0") >>>
Loose ends
Not all is rosy when gir and cross compilation meet, but we got very far, regardless there are still fixes to do.
Meson
Meson is still not complete, some packages like gdk-pixbuf
and atk
compile just fine. Others like libgusb
, less so:
diff --git a/srcpkgs/libgusb/template b/srcpkgs/libgusb/template index c2358c1125..00bcfdb940 100644 --- a/srcpkgs/libgusb/template +++ b/srcpkgs/libgusb/template @@ -1,13 +1,14 @@ # Template file for 'libgusb' pkgname=libgusb version=0.3.0 -revision=3 +revision=4 build_style=meson +build_helper="gir" configure_args="-Ddocs=false -Dgir=$(vopt_if gir true false) -Dvapi=$(vopt_if vala true false)" -hostmakedepends="pkg-config $(vopt_if gir gobject-introspection) - $(vopt_if vala vala)" -makedepends="libglib-devel libusb-devel libgudev-devel $(vopt_if vala vala-devel) usbutils" +hostmakedepends="pkg-config $(vopt_if vala vala)" +makedepends="libglib-devel libusb-devel libgudev-devel $(vopt_if vala vala-devel) + usbutils" short_desc="GLib wrapper around libusb1" maintainer="Juan RP <xtraeme@voidlinux.org>" license="LGPL-2.1-or-later" @@ -16,8 +17,9 @@ distfiles="http://people.freedesktop.org/~hughsient/releases/${pkgname}-${versio checksum=d8e7950f99b6ae4c3e9b8c65f3692b9635289e6cff8de40c4af41b2e9b348edc build_options="gir vala" +build_options_default="gir" if [ -z "$CROSS_BUILD" ]; then - build_options_default="gir vala" + build_options_default+=" vala" fi libgusb-devel_package() {
Looks good to me.
$ xbps-src -f -a aarch64 pkg libgusb [8/20] Generating GUsb-1.0.gir with a custom command. FAILED: gusb/GUsb-1.0.gir /usr/aarch64-linux-gnu/usr/bin/g-ir-scanner -pthread -I/usr/aarch64-linux-gnu/usr/include/gobject-introspection-1.0 -I/usr/aarch64-linux-gnu/usr/include/glib-2.0 -I/usr/aarch64-linux-gnu/usr/lib/glib-2.0/include --no-libtool --namespace=GUsb --nsversion=1.0 --warn-all --output gusb/GUsb-1.0.gir --c-include=gusb.h -I/builddir/libgusb-0.3.0/gusb -I/builddir/libgusb-0.3.0/build/gusb -I./. -I../. -I./gusb/. -I../gusb/. --filelist=/builddir/libgusb-0.3.0/build/gusb/bf6bc9e@@gusb@sha/GUsb_1.0_gir_filelist -L/builddir/libgusb-0.3.0/build/gusb --extra-library=gusb --include=Gio-2.0 --include=GObject-2.0 --symbol-prefix=g_usb --identifier-prefix=GUsb --pkg-export=gusb --cflags-begin -I./. -I../. -I./gusb/. -I../gusb/. -I/usr/aarch64-linux-gnu/usr/include/libmount -I/usr/aarch64-linux-gnu/usr/include/blkid -I/usr/aarch64-linux-gnu/usr/include/uuid -I/usr/aarch64-linux-gnu/usr/include/glib-2.0 -I/usr/aarch64-linux-gnu/usr/lib/glib-2.0/include -I/usr/aarch64-linux-gnu/usr/include/libusb-1.0 -D_FORTIFY_SOURCE=2 -I/usr/aarch64-linux-gnu/usr/include --cflags-end --library gusb -L/builddir/libgusb-0.3.0/build/gusb -L/usr/aarch64-linux-gnu/usr/lib --extra-library=gio-2.0 --extra-library=gobject-2.0 --extra-library=glib-2.0 --extra-library=usb-1.0 In file included from /builddir/libgusb-0.3.0/build/g-ir-cpp-se2xrgqu.c:4: /builddir/libgusb-0.3.0/build/gusb/gusb-version.h:31:2: error: #error "Only <gusb.h> can be included directly." #error "Only <gusb.h> can be included directly." ^~~~~ In file included from /usr/aarch64-linux-gnu/usr/include/bits/libc-header-start.h:33, from /usr/aarch64-linux-gnu/usr/include/limits.h:26, from /usr/lib/gcc/aarch64-linux-gnu/8.2.0/include-fixed/limits.h:194, from /usr/lib/gcc/aarch64-linux-gnu/8.2.0/include-fixed/syslimits.h:7, from /usr/lib/gcc/aarch64-linux-gnu/8.2.0/include-fixed/limits.h:34, from /usr/aarch64-linux-gnu/usr/lib/glib-2.0/include/glibconfig.h:11, from /usr/aarch64-linux-gnu/usr/include/glib-2.0/glib/gtypes.h:32, from /usr/aarch64-linux-gnu/usr/include/glib-2.0/glib/galloca.h:32, from /usr/aarch64-linux-gnu/usr/include/glib-2.0/glib.h:30, from /usr/aarch64-linux-gnu/usr/include/glib-2.0/gobject/gbinding.h:28, from /usr/aarch64-linux-gnu/usr/include/glib-2.0/glib-object.h:23, from /builddir/libgusb-0.3.0/gusb/gusb-context.h:25, from /builddir/libgusb-0.3.0/gusb/gusb-autocleanups.h:24, from /builddir/libgusb-0.3.0/build/g-ir-cpp-se2xrgqu.c:5: /usr/aarch64-linux-gnu/usr/include/features.h:381:4: warning: #warning _FORTIFY_SOURCE requires compiling with optimization (-O) [-Wcpp] # warning _FORTIFY_SOURCE requires compiling with optimization (-O) ^~~~~~~ Traceback (most recent call last): File "/usr/lib/python3.6/distutils/unixccompiler.py", line 107, in preprocess self.spawn(pp_args) File "/usr/lib/python3.6/distutils/ccompiler.py", line 909, in spawn spawn(cmd, dry_run=self.dry_run) File "/usr/lib/python3.6/distutils/spawn.py", line 36, in spawn _spawn_posix(cmd, search_path, dry_run=dry_run) File "/usr/lib/python3.6/distutils/spawn.py", line 159, in _spawn_posix % (cmd, exit_status)) distutils.errors.DistutilsExecError: command 'aarch64-linux-gnu-cpp' failed with exit status 1 During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/bin/g-ir-scanner.wrapped", line 106, in <module> sys.exit(scanner_main(sys.argv)) File "/usr/lib/gobject-introspection/giscanner/scannermain.py", line 555, in scanner_main ss = create_source_scanner(options, args) File "/usr/lib/gobject-introspection/giscanner/scannermain.py", line 459, in create_source_scanner ss.parse_files(filenames) File "/usr/lib/gobject-introspection/giscanner/sourcescanner.py", line 262, in parse_files self._parse(headers) File "/usr/lib/gobject-introspection/giscanner/sourcescanner.py", line 307, in _parse self._cpp_options) File "/usr/lib/gobject-introspection/giscanner/ccompiler.py", line 211, in preprocess extra_postargs=extra_postargs) File "/usr/lib/python3.6/distutils/unixccompiler.py", line 109, in preprocess raise CompileError(msg) distutils.errors.CompileError: command 'aarch64-linux-gnu-cpp' failed with exit status 1 ninja: build stopped: subcommand failed. => ERROR: libgusb-0.3.0_4: do_build: '${make_cmd} -C ${meson_builddir} ${makejobs} ${make_build_args} ${make_build_target}' exited with 1 => ERROR: in do_build() at common/build-style/meson.sh:125
The cause is known, -DGUSB_COMPILATION
is lost somewhere along the way.
Causing the header to #error
out.
musl
musl is very important to Void Linux so it is very nice to have gir be cross compilable to it.
But there are some problems to be debugged and corrected:
$ xbps-src -f -a aarch64-musl pkg gtk+3 FAILED: gdk-pixbuf/GdkPixbuf-2.0.gir /usr/aarch64-linux-musl/usr/bin/g-ir-scanner -pthread -I/usr/aarch64-linux-musl/usr/include/gobject-introspection-1.0 -I/usr/aarch64-linux-musl/usr/include/glib-2.0 -I/usr/aarch64-linux-musl/usr/lib/glib-2.0/include --no-libtool --namespace=GdkPixbuf --nsversion=2.0 --warn-all --output gdk-pixbuf/GdkPixbuf-2.0.gir --c-include=gdk-pixbuf/gdk-pixbuf.h --quiet -DGDK_PIXBUF_COMPILATION -I/builddir/gdk-pixbuf-2.38.0/gdk-pixbuf -I/builddir/gdk-pixbuf-2.38.0/build/gdk-pixbuf -I./. -I../. -I./gdk-pixbuf/pixops -I../gdk-pixbuf/pixops --filelist=/builddir/gdk-pixbuf-2.38.0/build/gdk-pixbuf/f4c7bd6@@gdk_pixbuf-2.0@sha/GdkPixbuf_2.0_gir_filelist --include=GModule-2.0 --include=Gio-2.0 --symbol-prefix=gdk --identifier-prefix=Gdk --pkg-export=gdk-pixbuf-2.0 --cflags-begin -I./. -I../. -I./gdk-pixbuf/pixops -I../gdk-pixbuf/pixops -I/usr/aarch64-linux-musl/usr/include/glib-2.0 -I/usr/aarch64-linux-musl/usr/lib/glib-2.0/include -I/usr/aarch64-linux-musl/usr/include/libmount -I/usr/aarch64-linux-musl/usr/include/blkid -I/usr/aarch64-linux-musl/usr/include/uuid -D_FORTIFY_SOURCE=2 -I/usr/aarch64-linux-musl/usr/include --cflags-end --library gdk_pixbuf-2.0 -L/builddir/gdk-pixbuf-2.38.0/build/gdk-pixbuf -L/usr/aarch64-linux-musl/usr/lib --extra-library=m --extra-library=gobject-2.0 --extra-library=glib-2.0 --extra-library=gmodule-2.0 --extra-library=gio-2.0 Error relocating /usr/aarch64-linux-musl/usr/lib/libz.so.1: unsupported relocation type 1026 Error relocating /usr/aarch64-linux-musl/usr/lib/libz.so.1: unsupported relocation type 1027 Error relocating /usr/aarch64-linux-musl/usr/lib/libz.so.1: unsupported relocation type 1025 collect2: error: ld returned 127 exit status linking of temporary binary failed: Command '['aarch64-linux-musl-gcc', '-o', '/builddir/gdk-pixbuf-2.38.0/build/tmp-introspectxv6j_hsz/GdkPixbuf-2.0', '-fstack-clash-protection', '-D_FORTIFY_SOURCE=2', '-O2', '-pipe', '-march=armv8-a', '-I/usr/aarch64-linux-musl/usr/include', '/builddir/gdk-pixbuf-2.38.0/build/tmp-introspectxv6j_hsz/GdkPixbuf-2.0.o', '-L.', '-Wl,-rpath,.', '-Wl,--no-as-needed', '-L/builddir/gdk-pixbuf-2.38.0/build/gdk-pixbuf', '-Wl,-rpath,/builddir/gdk-pixbuf-2.38.0/build/gdk-pixbuf', '-L/usr/aarch64-linux-musl/usr/lib', '-Wl,-rpath,/usr/aarch64-linux-musl/usr/lib', '-lgdk_pixbuf-2.0', '-lm', '-lgobject-2.0', '-lglib-2.0', '-lgmodule-2.0', '-lgio-2.0', '-lgio-2.0', '-lgobject-2.0', '-Wl,--export-dynamic', '-lgmodule-2.0', '-pthread', '-lglib-2.0', '-Wl,-z,relro', '-Wl,-z,now', '-Wl,--as-needed', '-L/usr/aarch64-linux-musl/usr/lib']' returned non-zero exit status 1. ninja: build stopped: subcommand failed. => ERROR: gdk-pixbuf-2.38.0_2: do_build: '${make_cmd} -C ${meson_builddir} ${makejobs} ${make_build_args} ${make_build_target}' exited with 1 => ERROR: in do_build() at common/build-style/meson.sh:125
O-oh...
Closing it out
As this post is published on my site i expect the pull request enabling gir cross to be merged, and i will probably be dealing with the inevitable fallout of any big change.
This has been a very nice journey and there is a few groups and people i would like to thank:
Yocto Project and Buildroot
2 Amazing projects dealing with Embedded Linux
Without their patches for the gobject-introspection
package, wrappers this
project would have taken probably 3 or 4 times as much time as it took.
Their prelink
package (which is in Void as prelink-cross
) is vital for
all this to work.
Enno "Gottox" Boland
Core, long-time Void Linux developer
While musl
cross doesn't work at the moment, a first step need to be made
and Gottox's work on making prelink-cross
compile on musl
is much
appreciated.
Rasmus "Cogitri" Thomsen
Core Exherbo developer, Void Linux contributor
Gracefully lent his VPS
for building packages and ran commands i requested
on his native aarch64
machine to test that it works.
If you feel you have helped me along the way with suggestions feel free to contact me on GitHub and i will include you here.
Final Thoughts
I'm satisfied with the current state, all arches that use glibc
now have gir and musl
is on the works.
GG.