Custom CMake Toolchains

To use a custom toolchain defined in an external CMake file, set these environment variables:

  • Set ZEPHYR_TOOLCHAIN_VARIANT to your toolchain’s name

  • Set TOOLCHAIN_ROOT to the path to the directory containing your toolchain’s CMake configuration files.

Zephyr will then include the toolchain cmake files located in the TOOLCHAIN_ROOT directory:

  • cmake/toolchain/<toolchain name>/generic.cmake: configures the toolchain for “generic” use, which mostly means running the C preprocessor on the generated Devicetree file.

  • cmake/toolchain/<toolchain name>/target.cmake: configures the toolchain for “target” use, i.e. building Zephyr and your application’s source code.

Here <toolchain name> is the same as the name provided in ZEPHYR_TOOLCHAIN_VARIANT See the zephyr files cmake/generic_toolchain.cmake and cmake/target_toolchain.cmake for more details on what your generic.cmake and target.cmake files should contain.

You can also set ZEPHYR_TOOLCHAIN_VARIANT and TOOLCHAIN_ROOT as CMake variables when generating a build system for a Zephyr application, like so:

west build ... -- -DZEPHYR_TOOLCHAIN_VARIANT=... -DTOOLCHAIN_ROOT=...
cmake -DZEPHYR_TOOLCHAIN_VARIANT=... -DTOOLCHAIN_ROOT=...

If you do this, -C <initial-cache> cmake option may useful. If you save your ZEPHYR_TOOLCHAIN_VARIANT, TOOLCHAIN_ROOT, and other settings in a file named my-toolchain.cmake, you can then invoke cmake as cmake -C my-toolchain.cmake ... to save typing.

Zephyr includes include/toolchain.h which again includes a toolchain specific header based on the compiler identifier, such as __llvm__ or __GNUC__. Some custom compilers identify themselves as the compiler on which they are based, for example llvm which then gets the toolchain/llvm.h included. This included file may though not be right for the custom toolchain. In order to solve this, and thus to get the include/other.h included instead, add the set(TOOLCHAIN_USE_CUSTOM 1) cmake line to the generic.cmake and/or target.cmake files located under <TOOLCHAIN_ROOT>/cmake/toolchain/<toolchain name>/.

When TOOLCHAIN_USE_CUSTOM is set, the other.h must be available out-of-tree and it must include the correct header for the custom toolchain. A good location for the other.h header file, would be a directory under the directory specified in TOOLCHAIN_ROOT as include/toolchain. To get the toolchain header included in zephyr’s build, the USERINCLUDE can be set to point to the include directory, as shown here:

west build -- -DZEPHYR_TOOLCHAIN_VARIANT=... -DTOOLCHAIN_ROOT=... -DUSERINCLUDE=...