Using Clang with OpenEmbedded/Yocto Project
Contents
Introductionπ
Clang is C/C++/ObjC frontend for LLVM compiler suite, supporting several architectures now. We have added support for clang into OpenEmbedded using a standalone layer
https://github.com/kraj/meta-clang
This layer requires OpenEmbedded-core layer as dependency
Configuring meta-clangπ
git clone git://github.com/openembedded/openembedded-core
cd openembedded-core
git clone git://github.com/openembedded/bitbake
git clone git://github.com/kraj/meta-clangSetupπ
. ./oe-init-build-env
Edit conf/bblayer.conf to add meta-clang
# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
LCONF_VERSION = "6"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= " \
/a/wheezy/home/kraj/work/openembedded-core/meta-clang \
/a/wheezy/home/kraj/work/openembedded-core/meta \
"
BBLAYERS_NON_REMOVABLE ?= " \
/a/wheezy/home/kraj/work/openembedded-core/meta \
"Selecting Default system Compilerπ
When meta-clang is added to layers it switches the default cross compiler for the system to be clang naturally. This selection is made by a variable which is assigned to choose clang if nothing else is selected
TOOLCHAIN ??= "clang"
One could start using GCC as default system compiler by setting TOOLCHAIN variable to βgccβ
TOOLCHAIN = "gcc"
This selection is done in configuration metadata files like conf/local.conf
Per-recipe ( package ) Compiler selectionπ
When using clang, not all components are compilable yet, hence we have to sometimes choose gcc for certain package recipe. In order to do it, you have to write a .bbappend in meta-clang, as an example below bbappend shows how we select gcc for building glibc
$ cat recipes-excluded/nonclangable/glibc_%.bbappend
TOOLCHAIN = "gcc"Current Statusπ
We can build/boot core-image-minimal for qemux86 and raspberryPi machines, of course that includes few components which are still compiled using gcc. But at this point, we are ready to port the packages to compile with clang
Compiling Kernel with Clangπ
For kernel we still use gcc, to start using clang for kernel we would require to override KERNEL_CC variable
kernel-arch.bbclass:KERNEL_CC = "${CCACHE}${HOST_PREFIX}gcc ${HOST_CC_KERNEL_ARCH} -fuse-ld=bfd"
To use clang
kernel-arch.bbclass:KERNEL_CC = "${CCACHE}${HOST_PREFIX}clang ${HOST_CC_KERNEL_ARCH} -fuse-ld=bfd"
This can also be done in kernel recipe too.
KERNEL_CC_forcevariable = "${CCACHE}${HOST_PREFIX}clang ${HOST_CC_KERNEL_ARCH} -fuse-ld=bfd"Compiler runtimeπ
We currently use gcc runtime by default with clang as well, meta-clang does have recipes for compiler-rt and libc++ which can be used to replace libgcc and libstdc++, at application level this selection can be made to depend on compiler-rt and libc++
SDKπ
We can generate OpenEmbedded SDK which will have both gcc and clang based cross compilers
bitbake -cpopulate_sdk core-image-minimal
Installing the SDK should be done something like this Installing the ToolchainΒΆ
To use clang in SDK one should use CLANGCC and CLANGCXX environment variables to reference the clang compilers