Embedded Handbook/General/Cross-compiling with Portage

From Gentoo Wiki
Jump to:navigation Jump to:search
General topics
Compiling with QEMU user chroot
Creating a cross-compiler
Cross-compiling with Portage
Cross-compiling the kernel
Frequently asked questions
Das U-Boot

Leverage Portage as a cross-compiling package manager.


There are a few important variables that will be used throughout this section:

Variable name Meaning
CBUILD The platform that (cross)compiles the binaries.
CHOST The platform that runs the compiled binaries.
ROOT The virtual / binaries are installed into.
PORTAGE_CONFIGROOT The virtual / Portage can find its config files (like make.conf).

These variables can be set by hand, but that obviously gets tedious very quickly. A better idea is to stick these into a shell script to avoid typing them each time.

Filesystem setup

Cross-compiling a system generally involves two directory structures. The differences between them can be difficult to understand, but they are important concepts to cross-compiling.

The first directory structure to consider is the sysroot. Please read the Introduction chapter for the definition of sysroot.

The second directory structure is the real root. This one is much simpler to understand: it's where the bootable stage3-like installation of Gentoo is located. This installation can then be copied to the target device.

The common convention is to use the /usr/${CTARGET}/ directory as the sysroot since the include/library directories in this tree are already encoded into the gcc cross-compiler for searching. Another directory could be used and then custom -I/-L paths could be added to the CPPFLAGS/LDFLAGS, but this has historically proven to be problematic in enough corner cases to be discouraged for practical use. In the embedded handbook, it will be assumed the sysroot is being used as the development ROOT.

A much slimmer/trimmed-down setup will be needed for the runtime system. The files removed from a normal installed package are the reason why this tree is not suitable for compiling against. If binary packages are built while installing into the sysroot, then those binary packages can be used in conjunction with the INSTALL_MASK variable to trim out most things. More information can be found in the man make.conf.

Intro: crossdev's wrappers

Simple wrapper scripts will be used to setup the environment variables to point to the appropriate locations, enabling cross-compilation using emerge. PORTAGE_CONFIGROOT and ROOT both point to the SYSROOT.

root #emerge --ask sys-devel/crossdev
crossdev's wrappers automatically configure the CBUILD and CHOST variables. Do not set them by hand in the environment!
Before any cross-emerge can be started, emerge-wrapper --init needs to be run. Instructions printed by emerge-wrapper should be followed before starting cross-emerge.

These tools can be used for both installing into the development root (sysroot) and into the runtime root. For the latter, the --root option should be specified. For example if an armv4tl-softfloat-linux-gnueabi toolchain has been merged via crossdev, then command can then be invoked like a normal emerge. But using the ctarget prefix:

root #armv4tl-softfloat-linux-gnueabi-emerge pkg0 pkg1 pkg2

By default these wrappers use the --root-deps=rdeps option to avoid the host dependencies from being pulled into the deptree. This can lead to incomplete deptrees. Therefore the --root-deps option can be used alone to see the full dependency graph.

By default crossdev will link to the generic embedded profile. This is done to simplify things, but the user may wish to use a more advanced targeted profile. The profile symlink can be updated in order to do that.

root #ln -s /var/db/repos/gentoo/profiles/default/linux/arm/17.0 ${SYSROOT}/etc/portage/make.profile

To change settings (such as USE flags) for the target system, edit the standard Portage config files:

root #${EDITOR} ${SYSROOT}/etc/portage/make.conf

Sometimes there are some additional, cross-compile-incompatible tests that must be overridden for configure scripts. To make this possible, crossdev exports a few variables to force the test to get the answer it should receive. This helps prevent bloat in packages which add local functions to workaround issues it assumes the target system has because it could not run the test while cross-compiling (because, of course, it's not running on the target system). From time-to-time additional variables may need to be added to these files in /usr/share/crossdev/include/site/ in order to get a package to compile. To figure out the variable that needs added, it is often as simple as grepping the configure script for the autoconf variable (which often begins with ac_) and adding it to the appropriate target file. This becomes easier with ebuild development experience.


If uninstalling and deleting the work is desired, the sysroot tree can be safely removed without affecting any native packages. Refer to the "Uninstalling" section in the crossdev guide.

This page is based on a document formerly found on our main website gentoo.org.
The following people contributed to the original document: Mike Frysinger, Ned Ludd, Robin H. Johnson, Alex Tarkovsky, Alexey Shvetsov, Raúl Porcel, Joshua Saddler on April 28, 2013.
They are listed here because wiki history does not allow for any external attribution. If you edit the wiki article, please do not add yourself here; your contributions are recorded on each article's associated history page.