meta-clang

repository·master·Indexed 42 days ago

https://github.com/kraj/meta-clang

A Yocto Project/OpenEmbedded layer that provides Clang/LLVM as an alternative to the default GNU compiler toolchain. It enables developers to use Clang for specific recipes or as the system-wide default compiler, including support for LLVM runtimes, SDK integration, and kernel builds with LTO.

Tokens
1.2K
Snippets
7
Records
7
Agent score
2%

What's inside meta-clang

  1. Switch between GNU and LLVM C++ runtimes

    master

    The TC_CXX_RUNTIME variable controls whether the system uses the GNU runtime (libgcc, libstdc++) or the LLVM runtime (compile-rt, llvm libunwind, libc++).

    • GNU Runtime (Default): TC_CXX_RUNTIME = "gnu". Works with both GCC and Clang.
    • LLVM Runtime: TC_CXX_RUNTIME = "llvm". Only tested with the Clang compiler.

    Note: Switching to LLVM runtime will still use crt files from the GNU compiler as LLVM's crt files are not yet integrated into the toolchain.

    To select a specific runtime for a single package, use a .bbappend:

    TC_CXX_RUNTIME:toolchain-clang:pn-<recipe> = "llvm"
    TC_CXX_RUNTIME = "llvm"
  2. Install and set up meta-clang

    master

    To use meta-clang in an OpenEmbedded or Yocto Project environment, clone the repository into your layer directory and add it using bitbake-layers.

    If using Poky (the Yocto Project reference distribution):

    1. Clone Poky and the meta-clang layer:
    git clone https://git.yoctoproject.org/git/poky
    cd poky
    git clone https://github.com/kraj/meta-clang.git
    1. Initialize the build environment:
    . ./oe-init-build-env
    1. Add the layer:
    bitbake-layers add-layer ../meta-clang

    Verify that meta-clang appears in your conf/bblayers.conf file.

    bitbake-layers add-layer ../meta-clang
  3. Configure Kernel build with Clang

    master

    Newer kernels (including Android kernels) support Clang compilation and LTO. To configure a kernel (e.g., linux-rockchip) to use Clang, use a .bbappend with the following settings:

    Basic Clang Toolchain Configuration

    TOOLCHAIN:forcevariable = "clang"
    
    DEPENDS:append:toolchain-clang = " clang-cross-${TARGET_ARCH}"
    KERNEL_CC:toolchain-clang = "${CCACHE}clang ${HOST_CC_KERNEL_ARCH} -fuse-ld=lld ${DEBUG_PREFIX_MAP} -fdebug-prefix-map=${STAGING_KERNEL_DIR}=${KERNEL_SRC_PATH}"
    KERNEL_LD:toolchain-clang = "${CCACHE}ld.lld"
    KERNEL_AR:toolchain-clang = "${CCACHE}llvm-ar"

    Enable LLVM Integrated Assembler (IAS)

    For older kernels, you may need to explicitly enable the integrated assembler:

    do_compile:prepend:toolchain-clang() {
    	export LLVM_IAS=1
    }
    
    do_compile_kernelmodules:prepend:toolchain-clang() {
    	export LLVM_IAS=1
    }

    To enable LTO, append a configuration file to the SRC_URI:

    FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
    SRC_URI:append:toolchain-clang = "\n\tfile://lto.cfg \n"

    And create an lto.cfg file with:

    CONFIG_LTO_CLANG=y
    CONFIG_LTO=y
    CONFIG_LTO_CLANG_THIN=y

    Note: CONFIG_LTO_CLANG is required for some Android-based kernels; mainline kernels usually auto-detect.

    TOOLCHAIN:forcevariable = "clang"
    
    DEPENDS:append:toolchain-clang = " clang-cross-${TARGET_ARCH}"
    KERNEL_CC:toolchain-clang = "${CCACHE}clang ${HOST_CC_KERNEL_ARCH} -fuse-ld=lld ${DEBUG_PREFIX_MAP} -fdebug-prefix-map=${STAGING_KERNEL_DIR}=${KERNEL_SRC_PATH}"
    KERNEL_LD:toolchain-clang = "${CCACHE}ld.lld"
    KERNEL_AR:toolchain-clang = "${CCACHE}llvm-ar"
  4. Set Clang as the default compiler

    master

    By default, meta-clang allows GCC to remain the system compiler. To switch the entire system to use Clang as the default cross-compiler, add the following to your local.conf:

    TOOLCHAIN ?= "clang"

    To select Clang for a specific recipe only, use a .bbappend file for that recipe containing:

    TOOLCHAIN = "clang"

    Note: Check conf/nonclangable.conf for a list of recipes that are not yet compatible with Clang.

    TOOLCHAIN ?= "clang"
  5. Configure LLVM provider for Clang

    master

    To save compile time and disk space, you can configure the build to use the LLVM packages provided by the Clang recipes instead of the default providers from the core layer. Add these settings to your configuration:

    PREFERRED_PROVIDER_llvm = "clang"
    PREFERRED_PROVIDER_llvm-native = "clang-native"
    PREFERRED_PROVIDER_nativesdk-llvm = "nativesdk-clang"
    PROVIDES:pn-clang = "llvm"
    PROVIDES:pn-clang-native = "llvm-native"
    PROVIDES:pn-nativesdk-clang = "nativesdk-llvm"
    PREFERRED_PROVIDER_llvm = "clang"
    PREFERRED_PROVIDER_llvm-native = "clang-native"
    PREFERRED_PROVIDER_nativesdk-llvm = "nativesdk-clang"
    PROVIDES:pn-clang = "llvm"
    PROVIDES:pn-clang-native = "llvm-native"
    PROVIDES:pn-nativesdk-clang = "nativesdk-llvm"
  6. Include Clang in the generated SDK

    master

    By default, the Clang-based cross-compiler is not included when running bitbake meta-toolchain or bitbake -cpopulate_sdk <image>. To ensure Clang is part of the generated SDK, add this to local.conf:

    CLANGSDK = "1"
    CLANGSDK = "1"
  7. Handle recipes that fail with Clang

    master

    If a component cannot be built with Clang, you can force it to use GCC by adding it to conf/nonclangable.inc or using a .bbappend:

    TOOLCHAIN:pn-<recipe> = "gcc"

    If a component fails specifically because it cannot build with libc++, you can force it to use libstdc++ via flags in a .bbappend:

    CXXFLAGS:append:pn-<recipe>:toolchain-clang = " -stdlib=libstdc++ "
    LDFLAGS:append:pn-<recipe>:toolchain-clang = " -stdlib=libstdc++ "
    TOOLCHAIN:pn-<recipe> = "gcc"