External Toolchain Support

FreeBSD needs support for external toolchains to ease testing of new compiler versions, support compilers that don't make sense to integrate into the base, and speed builds (by avoiding building of bootstrap compilers). This page documents efforts towards this.

Using pre-built toolchain packages

The simplest way to do this is with the pre-built toolchain packages. Toolchains are available via the devel/llvm## (for LLVM 10.0.0 and later), devel/xtoolchain-llvm<version> (for LLVM 8 and 9), and devel/freebsd-gcc<version> ports. For the GCC ports, architectures are provided as flavors and the resulting packages are named <arch>-gcc<version>. Once a toolchain is installed, it can be used with top-level system make targets such as buildworld and buildkernel via the CROSS_TOOLCHAIN variable to the name of the package (without the xtoolchain- prefix for LLVM toolchains). It can also be used with buildenv to build individual programs in the base system.

Cross-building with a pre-built toolchain package

For example, to build powerpc64 using GCC 6, you would do:

pkg install powerpc64-gcc6
make CROSS_TOOLCHAIN=powerpc64-gcc6 TARGET=powerpc TARGET_ARCH=powerpc64 buildworld
make CROSS_TOOLCHAIN=powerpc64-gcc6 TARGET=powerpc TARGET_ARCH=powerpc64 installworld DESTDIR=/sysroots/powerpc64
make CROSS_TOOLCHAIN=powerpc64-gcc6 TARGET=powerpc TARGET_ARCH=powerpc64 distribution DESTDIR=/sysroots/powerpc64

To build arm64 with LLVM11, you would do:

pkg install llvm11
make CROSS_TOOLCHAIN=llvm11 TARGET=arm64 buildworld
make CROSS_TOOLCHAIN=llvm11 TARGET=arm64 installworld DESTDIR=/sysroots/arm64
make CROSS_TOOLCHAIN=llvm11 TARGET=arm64 distribution DESTDIR=/sysroots/arm64

Use cross compiler to build native compiler

cd /usr/ports/base/binutils
make CROSS_TOOLCHAIN=powerpc64-gcc6 TARGET=powerpc TARGET_ARCH=powerpc64 CROSS_SYSROOT=/sysroots/powerpc64 package
cd /usr/ports/base/gcc6
make CROSS_TOOLCHAIN=powerpc64-gcc6 TARGET=powerpc TARGET_ARCH=powerpc64 CROSS_SYSROOT=/sysroots/powerpc64 package

Under the hood

The rest of this page provides details on how this works and how to override individual components if desired.


The XCC approach works with top level build targets (buildworld, buildkernel, etc) and overrides common make variables such as CC, CXX, and AS during the cross building portions of the build with values specified by the XCC, XCPP, XAS, etc variables. This method touches few files and is relatively easy to understand, but has drawbacks including the inability to build individual programs easily.

How to use

If is possible to replace both the compiler and binutils. It is possible to replace the compiler and use the built-in binutils. To replace binutils, you must also replace the compiler.

Both the compiler and binutils must be configured to support --sysroot to find headers and libraries.

Using an external compiler

To use an external compiler such as clang, set the variables XCC, XCXX, and XCPP when building and installing. You must generally set all three. For example:

$ make XCC=/usr/local/bin/clang XCXX=/usr/local/bin/clang++ XCPP=/usr/local/bin/clang-cpp buildworld

If your versions full paths end in cc, c++, and cpp, then you may use the CROSS_COMPILER_PREFIX variable to set all three (Note that this is a prefix, not a path):

$ ls /tmp/toolchain/
cross-c++       cross-cc        cross-cpp
$ make CROSS_COMPILER_PREFIX=/tmp/toolchain/cross- buildworld

If the compiler is clang and the target architecture is not the same as the build host then an appropriate target triple will be created and passed to clang to support native cross compilation.

Using an external binutils

To use an external binutils, set the XAS, XAR, XLD, XNM, XOBJDUMP, XRANLIB, and XSTRINGS. As with the compiler, there is a CROSS_BINUTILS_PREFIX variable. If the both the compiler and binutils have the same prefix a CROSS_TOOLCHAIN_PREFIX variable can be used to set both.


To use XCC, you must not set any of the variables that can be overridden by X* variables in /etc/make.conf or /etc/src.conf as Makefile.inc1 will be unable to change them.

See Also



ExternalToolchain (last edited 2020-09-15T15:51:08+0000 by BrooksDavis)