# Cross Compiling ## Overview When building packages, it might be necessary to use cross compilation depending on the target architecture. Cross compilation is *not* necessary if the target architecture can directly run on the host CPU (for example building an `x86_64` or `x86` package on a `x86_64` CPU). Multiple methods for cross compilation are implemented in pmbootstrap. For all methods except `cross-native`, a foreign arch chroot (with the target architecture) gets used during the build in addition to the native chroot. <!-- markdownlint-disable MD013 MD033 --> | Method | Native | Foreign | Speed | Limitations | |-----------------------------|--------|---------|--------|-------------------------------------------------------------------------| | QEMU only | | x | slow | So slow that it is desirable to<br>use other methods where possible. | | crossdirect<br>*(default)* | x | x | medium | Cross compiler runs natively,<br>everything else goes through QEMU. | | cross-native | x | | fast | Cannot depend on libraries<br>(works for kernel, u-boot, etc.). | | cross-native2 | x | x | fast | Works with e.g. meson build system.<br>Kernel builds not yet supported. | <!-- markdownlint-enable --> ## Methods ### QEMU only Enable this method with `options="!pmb:crossdirect"` in the `APKBUILD`. This method is the most reliable, but also the slowest. We only use it if faster methods don't work. GTK projects using `g-ir-scanner` (*"Generating […].gir with a custom command"*) are currently [known to fail](https://gitlab.postmarketos.org/postmarketOS/pmbootstrap/-/issues/2567) with other methods. ### Crossdirect This is the default method. This method works for almost all packages, and gives a good speed improvement over running everything in QEMU. However only the cross compilers run natively. Linkers and all other commands used during the build still need to run through QEMU and so these are still very slow. The native chroot gets mounted in the foreign arch chroot at `/native`. The [crossdirect](https://gitlab.postmarketos.org/postmarketOS/pmaports/-/blob/master/cross/crossdirect/APKBUILD) package gets installed into the native chroot and creates wrapper scripts pointing to the cross compilers. When building packages for `armv7`, the build runs in the foreign chroot and `PATH` will get prepended with `/native/usr/lib/crossdirect/armv7`. This leads to invoking the cross compiler from the native chroot, running at native speed, whenever calling the compiler from the foreign arch chroot. ### Cross-Native Enable this method with `options="pmb:cross-native"` in the `APKBUILD`. This method is only supported for packages that do not depend on foreign arch libraries, such bare metal software (kernel, u-boot), firmware packages or the postmarketos-artwork package. The whole build is done in the native chroot. Environment variables are used to tell abuild that it is a different arch package (`CARCH`) and to the kernel-style Makefiles that the cross compilers should be used. ### Cross-Native2 Enable this method with `options="pmb:cross-native2"` in the `APKBUILD`. This is supported since pmbootstrap 3.4, previous versions will ignore this option and use the crossdirect method instead. Packages from `makedepends_build=` in the `APKBUILD` are installed in the native chroot (where we run the build), and packages from `makedepends_host=` in the foreign chroot. Environment variables are used to run abuild in the native chroot and use its cross compilation features rather than running it and the build system through QEMU. This massively speeds up building when it works. The foreign chroot is mounted into the native chroot at `/sysroot`. Most build systems will refer to it as "sysroot", in abuild it is `CBUILDROOT`. Packages have been built successfully with cross-native2 and the following build systems: * meson * go build Where possible, we should try to migrate all packages that currently use crossdirect to cross-native2 to make them build faster. ## Language-specific ### Rust Rust packages can either be built with QEMU only, or with the crossdirect method. **Now that we have cross-native2 it makes more sense to try to get rust support working there as it will be faster and more reliable.** Rust support in crossdirect is still experimental. [pmaports!4234](https://gitlab.postmarketos.org/postmarketOS/pmaports/-/merge_requests/4234) (cross/crossdirect: improve rust handling) describes some of the problems with this approach. #### 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](https://doc.rust-lang.org/cargo/guide/cargo-home.html). 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 with crossdirect 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).