diff mbox series

toolchain/clang: prepend target host-sys to HOST_CC_ARCH

Message ID 20260812125954.688985-1-peter.marko@siemens.com
State Under Review
Headers show
Series toolchain/clang: prepend target host-sys to HOST_CC_ARCH | expand

Commit Message

Peter Marko Aug. 12, 2026, 12:59 p.m. UTC
From: Peter Marko <peter.marko@siemens.com>

This assignment was present in scarthgap meta-clang.
* commit adding it: [1]
* commit removing it from native case: [2]
* it was removed completely when migrating clang to oe-core

After migration from scarthgap to wrynose (or current master), clang
extra tools like clang-tidy do not work anymore.

Test recipe used for fix validation:

test-recipe.bb:
  SUMMARY = "clang-tidy demonstration program"
  SECTION = "examples"
  HOMEPAGE = "n/a"
  LICENSE = "GPL-2.0-only"
  LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/GPL-2.0-only;md5=801f80980d171dd6425610833a22dbe6"
  SRC_URI = "file://CMakeLists.txt file://hello-world.cpp"
  S = "${UNPACKDIR}"
  TOOLCHAIN = "clang"
  inherit cmake

CMakeLists.txt
  project(hello-world)
  cmake_minimum_required(VERSION 3.5)
  find_program(CLANG_TIDY NAMES clang-tidy)
  set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY}" "--checks=*")
  add_executable(${PROJECT_NAME} hello-world.cpp)

hello-world.cpp
  #include <iostream>
  int main() {
    std::cout << "Hello World!";
    return 0;
  }

I have asked AI agent to analyze clang sources for side-effects which
are mentioned in patch removing this with following result:

When a cmake recipe uses CMAKE_CXX_CLANG_TIDY (or runs clang-tidy in any
mode that passes the compile command via -- on the command line), CMake
invokes clang-tidy through its __run_co_compile path. This path
constructs a FixedCompilationDatabase from the arguments following --.
Inside FixedCompilationDatabase::loadFromCommandLine() the original
cross-compiler binary name (e.g. x86_64-poky-linux-clang++) is stripped
by stripPositionalArgs() and replaced with a dummy argv[0]. As a result
the target triple encoded in the cross-compiler name is never seen by
clang-tidy.

JSONCompilationDatabase (used when clang-tidy is run with -p <build_dir>)
wraps its commands with inferTargetAndDriverMode(), which calls
addTargetAndModeForProgramName() and would correctly inject
--target=x86_64-poky-linux. FixedCompilationDatabase has no equivalent
step, so the native clang-tidy falls back to the build-host default
triple and cannot locate C++ headers under the target sysroot:

  hello-world.cpp:1:10: error: 'iostream' file not found

The fix is to make the -target flag explicit in the compile commands.
The cross-compiler already has LLVM_DEFAULT_TARGET_TRIPLE compiled in as
HOST_SYS, so adding -target ${HOST_SYS} to HOST_CC_ARCH is a no-op for
the compiler itself. For clang-tidy and other Clang-based tools that
parse compile commands but do not inherit the binary's baked-in default
triple the flag is the only reliable channel to communicate the intended
target.

On a typical GNU/Linux host the GCC runtime is installed under a
vendor-qualified tuple (e.g. aarch64-linux-gnu/) that clang probes at
runtime. Providing an explicit -target aarch64-linux overrides that
probe and prevents clang-native from finding libgcc and crt objects,
which was the original motivation for removing the assignment.

[1] https://github.com/kraj/meta-clang/commit/503aa977b27be0506fb6ac21fbf9e8b049b82247
[2] https://github.com/kraj/meta-clang/commit/6da0abaa33b458a37b97f42e3755245e3220bf27

Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
 meta/classes/toolchain/clang.bbclass | 3 +++
 1 file changed, 3 insertions(+)
diff mbox series

Patch

diff --git a/meta/classes/toolchain/clang.bbclass b/meta/classes/toolchain/clang.bbclass
index 9a3cd0e584..862ecb5e10 100644
--- a/meta/classes/toolchain/clang.bbclass
+++ b/meta/classes/toolchain/clang.bbclass
@@ -34,6 +34,9 @@  LDFLAGS:append:class-nativesdk:x86-64 = " -Wl,-dynamic-linker,${base_libdir}/ld-
 LDFLAGS:append:class-nativesdk:aarch64 = " -Wl,-dynamic-linker,${base_libdir}/ld-linux-aarch64.so.1"
 LDFLAGS:append:class-cross-canadian = " -Wl,-dynamic-linker,${base_libdir}/placeholder/to/be/rewritten/by/sdk/installer"
 
+# helps extra tools like clang-tidy to find arch-specific macros and headers in a cross compile environment
+HOST_CC_ARCH:prepend = "-target ${HOST_SYS} "
+
 # do_populate_sysroot needs STRIP, do_package_qa needs OBJDUMP
 POPULATESYSROOTDEPS:append:class-target = " llvm-native:do_populate_sysroot"