아래는 (1) 커널 레시피만 Clang으로 빌드하는 방법과, (2) 배포판 전체를 Clang toolchain으로 전환하는 방법을 각각 “Yocto에서 실제로 적용 가능한 형태”로 정리한 것이다.
핵심 변수/흐름은 Yocto의 toolchain/clang 체계와 meta-clang의 TOOLCHAIN 스위치에 기반한다.
1) 커널 레시피만 Clang으로 빌드
개념
- 유저랜드/나머지 레시피는 GCC 유지
virtual/kernel만 kbuild에LLVM=1(또는CC=clang/LD=ld.lld등)을 전달해서 커널만 Clang으로 빌드- 전환 리스크가 가장 낮다(벤더 커널 포팅 시 보통 이 루트부터 시작)
커널에서 Clang 전환은 “Kconfig”가 아니라 **kbuild 변수(
LLVM=1,CC=clang등)**로 한다.
적용 절차
(1) clang/llvm 공급원 준비
가장 일반적인 선택은 meta-clang 레이어 추가다. meta-clang은 Yocto/OE에서 clang/llvm을 GCC와 공존시키고, “레시피 단위” 혹은 “전체 시스템” 단위로 선택 가능하게 해준다.
bitbake-layers add-layer /path/to/meta-clang
(2) 커널 레시피에만 TOOLCHAIN=clang 강제 (Yocto 레벨)
meta-clang 문서에 따르면 레시피 단위로 clang을 강제할 수 있다.
예: meta-my/recipes-kernel/linux/linux-%.bbappend
# 커널 레시피만 clang toolchain 사용
TOOLCHAIN = "clang"
(3) 커널 kbuild에 LLVM 변수 전달 (커널 레벨)
커널은 LLVM=1로 clang + (가능하면) lld/llvm-binutils를 묶어 선택한다.
EXTRA_OEMAKE:append = " LLVM=1"
ARM64에서 IAS 문제를 분리하고 싶으면(초기 포팅에서 자주 씀):
# 필요 시에만: GNU as로 조립 (IAS 회피)
EXTRA_OEMAKE:append = " LLVM_IAS=0"
(4) “진짜 clang으로 커널이 빌드됐는지” 확인
do_compile로그에서clang,ld.lld,llvm-objcopy같은 문자열 확인- 또는 커널 빌드 산출물의
include/generated/compile.h에서 compiler string 확인
커널만 clang 전환 시 추천 단계(원인 분리)
벤더 커널에서 깨지는 지점을 빨리 좁히려면 단계 적용이 좋다.
- 컴파일러만 clang
EXTRA_OEMAKE:append = " CC=clang"
- 링커까지 lld
EXTRA_OEMAKE:append = " CC=clang LD=ld.lld"
- 완전 전환(권장 최종)
EXTRA_OEMAKE:append = " LLVM=1"
2) 배포판 전체를 Clang toolchain으로 전환
개념
- “기본 툴체인” 자체를 clang으로 바꾸는 방식
- 영향 범위: 커널 + 유저랜드 + 툴 + 이미지 전체
- 장점: 시스템 전체를 clang 생태계로 통일 가능
- 단점: 비호환 레시피(Non-clangable) 처리가 핵심 난제
Yocto 문서 기준으로는 toolchain/clang이 있고, 이를 전역으로 선택하려면 PREFERRED_TOOLCHAIN_TARGET/NATIVE/SDK를 “clang”으로 설정하는 방식이 안내되어 있다.
meta-clang은 더 간단한 knob로 TOOLCHAIN ?= "clang"을 제공한다.
적용 절차 (meta-clang 기준)
(1) meta-clang 레이어 추가
bitbake-layers add-layer /path/to/meta-clang
(2) local.conf에서 기본 컴파일러를 clang으로 전환
meta-clang 문서의 기본 knob:
# conf/local.conf
TOOLCHAIN ?= "clang"
이 설정으로 “기본 cross-compiler”가 clang으로 전환된다(전역 적용).
(3) LLVM/Clang provider를 통일(선택)
meta-clang은 “llvm을 clang 레시피가 제공하도록” provider를 맞출 수 있는 예시를 제공한다.
PREFERRED_PROVIDER_llvm = "clang"
PREFERRED_PROVIDER_llvm-native = "clang-native"
PREFERRED_PROVIDER_nativesdk-llvm = "nativesdk-clang"
(4) C/C++ 런타임 선택(선택)
기본은 GNU 런타임(libgcc/libstdc++)를 유지할 수 있고, LLVM 런타임(libc++/compiler-rt 등)로도 갈 수 있다. meta-clang 문서에 knob가 있다.
# 기본은 gnu, 필요 시 llvm로
TC_CXX_RUNTIME = "gnu"
# TC_CXX_RUNTIME = "llvm"
(5) non-clangable 레시피 처리
meta-clang은 “clang으로 아직 안 되는 레시피 목록”을 별도 파일로 관리하라고 안내한다.
실무에서는 보통:
- 해당 레시피만
TOOLCHAIN="gcc"로 되돌림 (부분 예외) - 또는 패치로 clang 호환성 확보
- 또는 레시피/버전 교체
예: 특정 레시피만 GCC로 강제하는 bbappend
# meta-my/recipes-foo/bar/bar_%.bbappend
TOOLCHAIN = "gcc"
Yocto 공식 toolchain 선택 변수(문서 기반)
Yocto 문서상으로는 전역 전환 시 아래 변수를 “clang”으로 지정하는 흐름이 있다(상황에 따라 meta-clang knob와 병행/대체).
PREFERRED_TOOLCHAIN_TARGET = "clang"PREFERRED_TOOLCHAIN_NATIVE = "clang"PREFERRED_TOOLCHAIN_SDK = "clang"
(프로젝트/브랜치/레이어 조합에 따라 meta-clang의 TOOLCHAIN 방식이 더 단순하게 먹히는 경우가 많다.)
3) 두 방식 비교 요약
| 항목 | 커널만 clang | 배포판 전체 clang |
|---|---|---|
| 난이도 | 낮음 | 높음 |
| 적용 범위 | virtual/kernel 중심 | 거의 모든 레시피 |
| 실패 지점 | 커널(asm/ld.lld 등) 중심 | “안 빌드되는 레시피”가 대량 등장 가능 |
| 추천 상황 | 벤더 커널 포팅/검증 | clang 기반 플랫폼을 장기 운영하려는 경우 |
| 실전 전략 | 단계 적용(CC→LD→LLVM=1) | 예외 레시피를 gcc로 되돌리는 혼합 운영 |
참고
- Linux kernel: Building Linux with Clang/LLVM (
LLVM=1,LLVM_IAS등) - meta-clang:
TOOLCHAIN="clang"전역/레시피 단위 선택, LLVM provider, runtime knob - Yocto 문서:
toolchain/clang및PREFERRED_TOOLCHAIN_*/TOOLCHAIN전환 개념