pmbootstrap: Cross Compiling

From postmarketOS

This article explains how pmbootstrap builds foreign arch packages. Depending on the package type, one of these methods is used:

  • Native: kernels, bootloaders, firmware packages
  • Crossdirect: everything else
  • QEMU: fallback if crossdirect does not work (slow)

Native

Set options="pmb:cross-native" in the APKBUILD to use this method. pmaports CI scripts ensure that linux packages etc. use this method.

This is the fastest method, it gets used when the package does not have any dependencies on packages in the target architecture. pmbootstrap runs Alpine's abuild in the native chroot, installs the cross compiler related packages and sets environment variables like CARCH, CROSS_COMPILE and CC to instruct abuild and the kernels' build system (that also gets used in u-boot) to produce a foreign arch package.

Crossdirect

pmbootstrap uses this method by default.

The native chroot gets mounted in the foreign arch chroot (e.g. armhf) at /native. The crossdirect package gets installed into the native chroot, and creates wrapper scripts:

  • /native/usr/lib/crossdirect/armhf/gcc -> /native/usr/bin/armv6-alpine-linux-muslgnueabihf-gcc
  • /native/usr/lib/crossdirect/armhf/rustc -> /native/usr/bin/rustc --target=armv6-alpine-linux-musleabihf …

When building packages in the armhf chroot, PATH will get prepended with /native/usr/lib/crossdirect/armhf. This leads to invoking the cross compiler from the native chroot, running at native speed, whenever calling the compiler from the foreign arch chroot.

Rust

Rust support in crossdirect is still experimental. pmaports!4234 (cross/crossdirect: improve rust handling) describes some of the problems with it.

CARGO_HOME

If a program needs to download git repositories of dependencies with cargo (ideally they are bundled with the source tarball and don't need to be downloaded), then these git repositories are cached with pmbootstrap. This works as long as the program does not override CARGO_HOME. GNOME podcasts does this for example, so if building gnome-podcasts from the git repository with pmbootstrap build --src, patch out the override of CARGO_HOME so the dependencies do not get downloaded for every build.

Packaging caveats

  • cargo auditable build is unsupported and falls back to compiling in QEMU. Change it to cargo build to build the package with the native compiler.
  • Running tests doesn't really work (e.g. when building squeekboard, the tests hang and time out).

QEMU

Use pmbootstrap --no-cross or set options="!pmb:crossdirect" in the APKBUILD to use this method.

pmbootstrap installs everything into the foreign arch chroot and runs the build through QEMU user emulation. This is the most reliable method, but it is much slower than cross compiling. Use this as workaround if your package does not build with crossdirect.

See also