Cross Compiling FreeBSD for Fun and Profit
- Obtaining FreeBSD
- Setting up Build Environment
- Building World
- What's Next
For the sake of illustration, the document assumes that:
All files will be placed under /home/bob .
The architecture being built will be (big-endian) ARM, aka armeb.
The installed world will be placed under /home/bob/my-armeb.
Any line preceded by a % is to be executed in a system shell.
- The reader can specify make variables in one of three ways:
In a custom make.conf file and call make with \_\_MAKE_CONF=/full/path/to/make.conf .
- Set the variables in the environment, e.g. with env, export, or setenv.
Explicitly on the command line. NOTE: this is how the writeup specifies the values.
The reader can obtain the sources as noted in the Handbook chapter titled Obtaining FreeBSD. The reader should place the sources in /home/bob/src.
Setting up Build Environment
For architectures that are supported by FreeBSD, cross-building is relatively easy. For architectures that FreeBSD doesn't support, more work is required.
The FreeBSD build system uses three environment variables to control which platform to build (TARGET), which target architecture to build (TARGET_ARCH), and where to put the results (MAKEOBJDIRPREFX). By default, FreeBSD builds the current architecture and places the results in /usr/obj, or in this example /home/bob/obj.
When cross-compiling however, FreeBSD places binaries in $MAKEOBJDIRPREFIX/$TARGET (for cases where $TARGET == $TARGET_ARCH, e.g. amd64) or $MAKEOBJDIRPREFIX/$TARGET.$TARGET_ARCH (for cases where $TARGET != $TARGET_ARCH). In this example, the directory used will be /home/bob/obj/arm.armeb.
Note that a non-default value of MAKEOBJDIRPREFIX must be passed to make as an environment variable. It cannot be set as an argument to make directly.
make.conf / src.conf
A standard make.conf and src.conf file can contain variables or make snippets which tune build behavior. /usr/share/examples/etc/make.conf has more details on some recommended make.conf tunable items, and src.conf(5) lists some of the variables that one could put in src.conf . The following notes some potential pitfalls in using these files for cross-compiling, make universe, make tinderbox, etc:
- Explicitly setting CPUTYPE. The following incorrect example would explicitly attempt to build binaries optimizing for the core2 Intel architecture:
- The reader should instead set the CPUTYPE as follows:
- Explicitly setting KERNCONF. The following incorrect example would explicitly build the XEN KERNCONF (which only exists for i386 and amd64):
- The reader should instead set KERNCONF as follows:
Building and Installing World
The following subsections show the reader how they could build and install world for the big-endian ARM architecture from scratch.
Go to the Source Directory
% cd /home/bob/src
% env MAKEOBJDIRPREFIX=/home/bob/obj make buildworld TARGET=arm TARGET_ARCH=armeb
- First and foremost, one must create the install directory:
% mkdir /home/bob/my-armeb
- Then one must run make installworld to install the binaries produced in buildworld:
% env MAKEOBJDIRPREFIX=/home/bob/obj make installworld DESTDIR=/home/bob/my-armeb TARGET=arm TARGET_ARCH=armeb
And last but not least, one must run make distribution to populate the world with important files from /etc:
% env MAKEOBJDIRPREFIX=/home/bob/obj make distribution DESTDIR=/home/bob/my-armeb TARGET=arm TARGET_ARCH=armeb
NOTE: You could invoke mergemaster instead of running make distribution; mergemaster does a few things that make distribution does not do; see The Canonical Way to Update Your System for more details, and please consult mergemaster(8).
The above example demonstrated how one could build world and install world with armeb. This should provide you with the building blocks required to build the FreeBSD base system for any cross-compilation environment.