FreeBSD: poudriere cross compiling (ARM)

Poudriere permet de réaliser du cross compiling et donc de compiler des cibles d'une autre architecture. Nous allons ici prendre l'exemple d'une architecture amd64 cross-compilant vers ARM6 pour un Raspberry PI 2.

Préparation de la jail poudrière

Tout d'abord on va télécharger une image RPI2 viable depuis le miroir FreeBSD puis la décompresser

fetch http://ftp.freebsd.org/pub/FreeBSD/releases/ISO-IMAGES/11.0/FreeBSD-11.0-RELEASE-arm-armv6-RPI2.img.xz
unxz FreeBSD-11.0-RELEASE-arm-armv6-RPI2.img.xz

On va ensuite la rendre disponible au niveau filesystem grâce à l'utilitaire mdconfig

mdconfig -a -t vnode -f FreeBSD-11.0-RELEASE-arm-armv6-RPI2.img
mount /dev/md0s2a /mnt

On va maintenant supprimer le flag pour le firstboot (inutile ici nous serons dans une jail de build) et créer le répertoire /usr/local/bin pour poudriere

rm /mnt/firstboot
mkdir -p /mnt/usr/local/bin

L'image est maintenant prête on va créer l'archive pour poudriere:

tar -cpf /tmp/FreeBSD-11.0-RELEASE-arm-armv6-RPI2.tar .

Nous pouvons maintenant créer la jail

poudriere jail -c -j 11-arm6 -m tar=/tmp/FreeBSD-11.0-RELEASE-arm-armv6-RPI2.tar -a arm.armv6 -v 11.0-RELEASE

Support de la compilation ARM

Tout d'abord on va avoir besoin de qemu-user-static pour réaliser cette cross compilation. Il a 2 avantages:

  • Il n'a pas de dépendances particulières
  • Le binaire étant statique il va permettre à poudrière de s'éxecuter correctement sans devoir copier des librairies dynamiques supplémentaires dans la jail
pkg install qemu-user-static

Ajoutez maintenant l'émulateur ARM aux interpréteurs utilisables par poudriere

binmiscctl add armv6 --interpreter "/usr/local/bin/qemu-arm-static"
      --magic
      "\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00"
      --mask
      "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"
      --size 20 --set-enabled

Cross-compiling !

L'environnement est prêt, il ne reste plus qu'à lancer la compilation, par exemple de zsh

poudriere bulk -j 11-arm6 -p default shells/zsh
 [00:00:00] ====>> Cross-building ports for arm.armv6 on amd64 requires QEMU
 [00:00:00] ====>> Creating the reference jail... done
 [00:00:00] ====>> Mounting system devices for 11-arm6-default
 [00:00:00] ====>> Mounting ports/packages/distfiles
 [00:00:00] ====>> Using packages from previously failed build
 [00:00:00] ====>> Mounting packages from: /usr/local/poudriere/data/packages/11-arm6-default
 [00:00:00] ====>> Copying /var/db/ports from: /usr/local/etc/poudriere.d/11-arm6-options
 [00:00:00] ====>> Raising MAX_EXECUTION_TIME and NOHANG_TIME for QEMU
 [00:00:00] ====>> Copying latest version of the emulator from: /usr/local/bin/qemu-arm-static
 /etc/resolv.conf -> /usr/local/poudriere/data/.m/11-arm6-default/ref/etc/resolv.conf
 [00:00:00] ====>> Starting jail 11-arm6-default
 [00:00:01] ====>> Logs: /usr/local/poudriere/data/logs/bulk/11-arm6-default/2017-01-13_22h51m51s
 [00:00:01] ====>> Loading MOVED
 [00:00:02] ====>> Calculating ports order and dependencies
 [00:00:32] ====>> Sanity checking the repository
 [00:00:32] ====>> Checking packages for incremental rebuild needed
 [00:00:32] ====>> Deleting stale symlinks
 [00:00:32] ====>> Deleting empty directories
 [00:00:32] ====>> Cleaning the build queue
 [00:00:33] ====>> Recording filesystem state for prepkg... done
 [00:00:33] ====>> Building 36 packages using 2 builders
 [00:00:33] ====>> Starting/Cloning builders
 [00:00:35] ====>> Hit CTRL+t at any time to see build progress and stats
 [00:00:35] ====>> [01][00:00:00] Starting build of ports-mgmt/pkg

Votre jail de cross compilation est maintenant opérationnelle, vous pouvez compiler sur un vrai CPU et ne plus attendre des jours que votre Raspberry PI compile X11.