Skip to content

toolchains: combine host variants #90670

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

nashif
Copy link
Member

@nashif nashif commented May 27, 2025

Combine toolchains provided by the host into one variant. This includes
both gcc and llvm installationt typically coming from the distribution
(on Linux).

Both gcc and llvm are now part of the 'host' variant, the default is the
gnu compiler, so setting

ZEPHYR_TOOLCHAIN_VARIANT=host

Will select the gnu compiler. To select llvm or any other compuler
provided in this variant, use the follwoing format:

ZEPHYR_TOOLCHAIN_VARIANT=<variant>/<compiler>

The following will select llvm:

ZEPHYR_TOOLCHAIN_VARIANT=host/llvm

Although gnu is the default, it can also be selected using the above
syntax:

ZEPHYR_TOOLCHAIN_VARIANT=host/gcc

This commit removes the llvm variant for now, it should be deperecated
in another commit to follow.

Resolves #90239

Signed-off-by: Anas Nashif anas.nashif@intel.com

Combine toolchains provided by the host into one variant. This includes
both gcc and llvm installationt typically coming from the distribution
(on Linux).

Both gcc and llvm are now part of the 'host' variant, the default is the
gnu compiler, so setting

	ZEPHYR_TOOLCHAIN_VARIANT=host

Will select the gnu compiler. To select llvm or any other compuler
provided in this variant, use the follwoing format:

	ZEPHYR_TOOLCHAIN_VARIANT=<variant>/<compiler>

The following will select llvm:

	ZEPHYR_TOOLCHAIN_VARIANT=host/llvm

Although gnu is the default, it can also be selected using the above
syntax:

	ZEPHYR_TOOLCHAIN_VARIANT=host/gcc

This commit removes the llvm variant for now, it should be deperecated
in another commit to follow.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
@@ -0,0 +1,9 @@

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing SPDX/license header

# This file intentionally left blank.
if(TOOLCHAIN_VARIANT_COMPILER STREQUAL "gnu" OR
TOOLCHAIN_VARIANT_COMPILER STREQUAL "default")
include(${ZEPHYR_BASE}/cmake/toolchain/host/gnu/target.cmake)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
include(${ZEPHYR_BASE}/cmake/toolchain/host/gnu/target.cmake)
include(${ZEPHYR_BASE}/cmake/toolchain/host/gnu/target.cmake)

Copy link

@tejlmand
Copy link
Collaborator

tejlmand commented May 28, 2025

I'm very much in favor of cleaning up Zephyr's toolchain variants.

However, I think removing llvm as it's own variant is a mistake.

ZEPHYR_TOOLCHAIN_VARIANT=llvm is NOT host compiling only.

It also supports cross-compilation, both using the LLVM provided with your favorite distribution (such as Ubuntu) or using a dedicated LLVM toolchain build, such as: Arm Toolchain for Embedded (ATfE), https://docs.zephyrproject.org/latest/develop/toolchains/arm_toolchain_for_embedded.html#arm-toolchain-for-embedded-atfe.

For example, I can use LLVM from Ubuntu to build for an nRF52840dk, all I need is the correct compiler-rt for my target and using lld as linker. lld is provided as part of the llvm package.
compiler-rt is needed as trying to use libgcc for an x86 when cross-linking for armv7m won't work.

Using lld and compiler-rt on the other hand works like a charm:

$ cmake -GNinja -DBOARD=nrf52840dk/nrf52840 -Bbuild samples/hello_world/ -DCONFIG_COMPILER_RT_RTLIB=y -DCONFIG_LLVM_USE_LLD=y
Loading Zephyr default modules (Zephyr repository).
-- Application: /projects/github/ncs/zephyr/samples/hello_world
...
-- Board: nrf52840dk, qualifiers: nrf52840
...
-- Found toolchain: llvm (clang/ld)
...
-- Found LlvmLld: /usr/bin/ld.lld (found suitable version "14.0.0", minimum required is "14.0.0")
-- The C compiler identification is Clang 18.1.8
-- The CXX compiler identification is Clang 18.1.8
-- The ASM compiler identification is Clang with GNU-like command-line
-- Found assembler: /usr/bin/clang
...
-- Configuring done (8.5s)
-- Generating done (0.1s)
-- Build files have been written to: /projects/github/ncs/zephyr/build
$

Let's see what clang reports:

$ /usr/bin/clang --version
Ubuntu clang version 18.1.8 (++20240731024944+3b5b5c1ec4a3-1~exp1~20240731145000.144)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$

and let's build:

$ ninja -Cbuild
...
[1099/1099] Linking C executable zephyr/zephyr.elf
Generating files from /projects/github/ncs/zephyr/build/zephyr/zephyr.elf for board: nrf52840dk
$

So a successful build using clang from host system (Ubuntu), of course with a corresponding bare-metal compiler-rt.
Which in this case is:

/usr/bin/clang --target=armv7m-none-eabi... -o zephyr/zephyr.elf ... -L/usr/lib/llvm-18/lib/clang/18/lib/baremetal /projects/github/ncs/zephyr/build/modules/picolibc/libc.a -lclang_rt.builtins-armv7m

Instructions on how to cross-compile compiler-rt are described here: https://llvm.org/docs/HowToCrossCompileBuiltinsOnArm.html

@tejlmand
Copy link
Collaborator

and of course, that exact same llvm toolchain also works when building for the host (native_sim/native):

$ cmake -GNinja -DBOARD=native_sim/native -Bbuild samples/hello_world/ -DCONFIG_COMPILER_RT_RTLIB=y -DCONFIG_LLVM_USE_LLD=y
Loading Zephyr default modules (Zephyr repository).
-- Application: /projects/github/ncs/zephyr/samples/hello_world
...
-- Board: native_sim, qualifiers: native
...
-- Found toolchain: llvm (clang/ld)
...
-- Found LlvmLld: /usr/bin/ld.lld (found suitable version "14.0.0", minimum required is "14.0.0")
-- The C compiler identification is Clang 18.1.8
-- The CXX compiler identification is Clang 18.1.8
-- The ASM compiler identification is Clang with GNU-like command-line
-- Found assembler: /usr/bin/clang
...
-- Configuring done (7.5s)
-- Generating done (0.1s)
-- Build files have been written to: /projects/github/ncs/zephyr/build
$ ninja -Cbuild 
ninja: Entering directory `build'
...
[85/87] Linking C executable zephyr/zephyr.elf
Generating files from /projects/github/ncs/zephyr/build/zephyr/zephyr.elf for board: native_sim
[87/87] Running utility command for native_runner_executable
$ ./build/zephyr/zephyr.exe
*** Booting Zephyr OS build v4.1.0-3791-g14b4e30cdf62 ***
Hello World! native_sim/native

so one toolchain, llvm, regardless of host or embedded target build.

@nashif
Copy link
Member Author

nashif commented May 28, 2025

@tejlmand

ZEPHYR_TOOLCHAIN_VARIANT=llvm is NOT host compiling only.

you probably need to read this: #90239 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Overhaul toolchain configuration and make ZEPHYR_TOOLCHAIN_VARIANT scalable
3 participants