Yocto 환경에서 커널에 Clang/LLVM 빌드 환경 적용하기

아래는 (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 전환 시 추천 단계(원인 분리)

벤더 커널에서 깨지는 지점을 빨리 좁히려면 단계 적용이 좋다.

  1. 컴파일러만 clang
EXTRA_OEMAKE:append = " CC=clang"
  1. 링커까지 lld
EXTRA_OEMAKE:append = " CC=clang LD=ld.lld"
  1. 완전 전환(권장 최종)
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/clangPREFERRED_TOOLCHAIN_*/TOOLCHAIN 전환 개념

답글 남기기