Cross Building FreeBSD

I’ll assume that you are familiar with FreeBSD’s build system. If not, there are many resources available on the web. One of the better ones is the FreeBSD handbook. Future articles will build on this base, hopefully with sufficient links.
Each FreeBSD platform has a MACHINE and a MACHINE_ARCH that uniquely define it. The MACHINE_ARCH is the CPU family that executes the object code. MACHINE_ARCH is something like „i386“ or „sparc64.“ Some CPU families come in different flavors that are mutually incompatible (such as MIPS processors using different byte ordering). These families would get a different MACHINE_ARCH for each flavor (so you’d have mipseb and mipsel, for example, to distinguish the two different flavors of MIPS CPUs). If you are familar with the gnu compilers and such, this field roughly corresponds to „CPU“ field of their „CPU-MANUFACTURER-OS“ identifier. I say „corresponds“ because FreeBSD uses „amd64“ as the MACHINE_ARCH for AMD’s extensions to the x86 architecture (the official name of the architecture), while gcc uses the older x86_64 designation.
MACHINE defines the way the machine is put together. Often times machines are build with the same CPU, but with differing glue chips and support software. In cases like this, if the machines are very similar, FreeBSD will support that with one MACHINE type. In other cases, the differences are large enough to warrant an entirely separate MACHINE for that machine. What differentiates one MACHINE type from another with the same MACHINE_ARCH are things like BIOS interface, boot procedure, disk partitioning, and expansion bus technologies. For example, the FreeBSD/i386 and FreeBSD/pc98 platforms both execute on i386 compatible CPUs, but they have completely different bus topologies, boot procedures, BIOS interfaces, and disk layout.
When one builds FreeBSD on one platform to execute on another platform, that is called cross compiling. Cross compilation support is integrated into the normal FreeBSD build system. It is activated by defining TARGET and TARGET_ARCH of the machine you are targeting and using the normal make targets. For example:

make TARGET=arm TARGET_ARCH=arm buildworld

will build the entire userland portion of the system for an ARM machine. Similarly, the following:

make TARGET=arm TARGET_ARCH=arm installworld DESTDIR=/foo

will install these components into the directory tree /foo. One can even build and install a kernel for the target platform:

make TARGET=arm TARGET_ARCH=arm KERNCONF=BONGO kernel DESTDIR=/foo