Preface

This is a continuation of crossing the gir, it is highly recommended you read it before.

Introduction

Today we are going to make vala work with cross compilation, it currently already compiles with it, but there are a few problems with projects that generate vala bindings.

gnu-configure

Starting with autoconf which was the easier fix, this time around autoconf does the right thing. It uses pkg-config to find the variables to find the directories it needs to search, namely vapidir and vapidir_versioned.

/usr/share/aclocal/vapigen.m4

  AS_CASE([$enable_vala],
    [yes], [
      VAPIGEN=`$PKG_CONFIG --variable=vapigen $vapigen_pkg_name`
      VAPIGEN_MAKEFILE=`$PKG_CONFIG --variable=datadir $vapigen_pkg_name`/vala/Makefile.vapigen
      AS_IF([test "x$2" = "x"], [
          VAPIGEN_VAPIDIR=`$PKG_CONFIG --variable=vapidir $vapigen_pkg_name`
        ], [
          VAPIGEN_VAPIDIR=`$PKG_CONFIG --variable=vapidir_versioned $vapigen_pkg_name`
        ])
    ])

As you can see it makes use of pkg-config --variable to get the directories. as we know, the --variable call doesn't prefix it with PKG_CONFIG_SYSROOT_DIR, which is the directory where the cross components are installed.

As seen previously this can be fixed trivially, just prefix the variables in the pkg-config file with ${pc_sysrootdir}.

diff --git a/srcpkgs/vala/template b/srcpkgs/vala/template
index 5dcf0a9f870..f00fd05d87f 100644
--- a/srcpkgs/vala/template
+++ b/srcpkgs/vala/template
@@ -1,7 +1,7 @@
 # Template file for 'vala'
 pkgname=vala
 version=0.42.5
-revision=1
+revision=2
 build_style=gnu-configure
 configure_args="--disable-graphviz"
 hostmakedepends="flex libxslt pkg-config automake libtool"
@@ -28,6 +28,13 @@ pre_configure() {
    autoreconf -fi
 }
 
+post_install() {
+	vsed -e 's|^datadir=.*|datadir=${pc_sysrootdir}/${datarootdir}|g' \
+		 -e 's|^vapidir=.*|vapidir=${pc_sysrootdir}/${datadir}/vala/vapi|g' \
+		 -e 's|^vapidir_versioned=.*|vapidir_versioned=${pc_sysrootdir}/${datadir}/vala-0.42/vapi|g' \
+		 -i ${DESTDIR}/usr/lib/pkgconfig/vapigen-0.42.pc
+}
+
 libvala_package() {
    short_desc+=" - shared library"
    pkg_install() {

This fixes the problem for autoconf projects making use of vapigen.m4.

Meson

meson is more complicated, it doesn't use pkg-config files to set those values, it just runs vapigen itself and hopes for the best.

If they used the pkg-config file the fix for autoconf would also apply here and i could end this article a few sentences ago.

On the bright side we now have a nice opportunity to talk about another nice thing xbps-src provides: wrappers.

xbps-src wrappers

xbps-src wrappers are executable files that are put in /builddir/.xbps-/wrappers and the PATH variable is prefixed with it.

It is used extensively in xbps-src, one example is ignoring -L/usr/lib during cross compilation, there are also wrappers for -config binaries provided by projects, some of which are insanely in ELF format, making them impossible to use in cross compilation.

Today we are going to wrap vapigen, the tool used to generate vala bindings we need.

diff --git a/common/hooks/pre-configure/02-script-wrapper.sh b/common/hooks/pre-configure/02-script-wrapper.sh
index 59aa4eda3a4..9eac4843ff1 100644
--- a/common/hooks/pre-configure/02-script-wrapper.sh
+++ b/common/hooks/pre-configure/02-script-wrapper.sh
@@ -78,6 +78,21 @@ _EOF
    ln -sf ${XBPS_CROSS_TRIPLET}-pkg-config ${XBPS_WRAPPERDIR}/pkg-config
 }
 
+vapigen_wrapper() {
+	if [ ! -x /usr/bin/vapigen ]; then
+		return 0
+	fi
+	[ -x ${XBPS_WRAPPERDIR}/vapigen ] && return 0
+	cat >>${XBPS_WRAPPERDIR}/vapigen<<_EOF
+#!/bin/sh
+exec /usr/bin/vapigen \\
+	 --vapidir=${XBPS_CROSS_BASE}/usr/share/vala/vapi \\
+	 --vapidir=${XBPS_CROSS_BASE}/usr/share/vala-0.42/vapi \\
+	 --girdir=${XBPS_CROSS_BASE}/usr/share/gir-1.0 "\$@"
+_EOF
+	chmod 755 ${XBPS_WRAPPERDIR}/vapigen
+}
+
 install_wrappers() {
    local fname
 
@@ -120,6 +135,7 @@ hook() {
 
    install_cross_wrappers
    pkgconfig_wrapper
+	vapigen_wrapper
    generic_wrapper icu-config
    generic_wrapper libgcrypt-config
    generic_wrapper freetype-config

Looks simple enough:

  1. Check if vapigen is installed.
  2. Check if vapigen wrapper isn't already installed.
  3. Write it out, passing the args we need and then the rest.
  4. Make it executable

This should be the final result for cross compiling to aarch64:

#!/bin/sh
exec /usr/bin/vapigen \
     --vapidir=/usr/aarch64-linux-gnu/usr/share/vala/vapi \
     --vapidir=/usr/aarch64-linux-gnu/usr/share/vala-0.42/vapi \
     --girdir=/usr/aarch64-linux-gnu/usr/share/gir-1.0 "$@"

All done now, meson and autoconf are fixed.