diff mbox series

[1/2] clang: fix IsOpenEmbedded() detection for CLANG_EXTRA_OE_DISTRO entries

Message ID 20260812161341.822689-1-f_l_k@t-online.de
State New
Headers show
Series [1/2] clang: fix IsOpenEmbedded() detection for CLANG_EXTRA_OE_DISTRO entries | expand

Commit Message

Markus Volk Aug. 12, 2026, 4:13 p.m. UTC
do_preconfigure builds Distro::IsOpenEmbedded() from CLANG_EXTRA_OE_DISTRO,
but two bugs silently defeat OE-host detection for any distro beyond
the shipped default (poky:poky).

The check is assembled by appending each entry as 'NAME ||' and
stripping the trailing operator, so only the first entry gets a
'DistroVal ==' prefix.
With more than one entry this generates e.g.:
 bool IsOpenEmbedded() const { return DistroVal == POKY ||WAYLAND_DESKTOP; }
and compiles but IsOpenEmbedded() then always returns true regardless of the
actual distro, since a non-zero enumerator is truthy -- the check becomes
disabled rather than extended.

Separately, the .Case() match string is built from the
underscore-converted identifier (needed since it doubles as a C++
enumerator name) instead of the raw distro id as it appears in
/etc/os-release. Since detection compares directly against the raw
ID= value, any distro name containing a hyphen never matches.

This only surfaces on a self-hosted OE build host (e.g. via
packagegroup-core-buildessential/-core-sdk) with a non-'poky' DISTRO
registered in CLANG_EXTRA_OE_DISTRO. Mainstream distros never hit
this path, since their native GCC keeps crt objects and headers
together in one directory that clang's default search already finds.
OE-built hosts split these across two directories, which is exactly
what the IsOpenEmbedded()-gated candidate exists to handle -- with it
disabled, native clang-toolchain builds (e.g. libcxx-native) fail:

    /usr/bin/x86_64-oe-linux-ld: cannot find crtbeginS.o: No such file or directory
    /usr/bin/x86_64-oe-linux-ld: cannot find -lgcc: No such file or directory

Verified with debug instrumentation in
GCCInstallationDetector::ScanLibDirForGCCTriple(): with both fixes
applied, clang -v correctly reports:

    Found candidate GCC installation: /usr/lib/x86_64-oe-linux/16.1.0
    Selected GCC installation: /usr/lib/x86_64-oe-linux/16.1.0

Build each comparison explicitly and join with ' || ', and use the
raw (hyphenated) distro id for the .Case() match while keeping the
underscore-converted identifier only for the generated C++
enumerator/method names.

Signed-off-by: Markus Volk <f_l_k@t-online.de>
Co-authored-by: Claude <noreply@anthropic.com>
---
 meta/recipes-devtools/clang/llvm-project-source.inc | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/meta/recipes-devtools/clang/llvm-project-source.inc b/meta/recipes-devtools/clang/llvm-project-source.inc
index 85b5ef06dc..5cd08d4085 100644
--- a/meta/recipes-devtools/clang/llvm-project-source.inc
+++ b/meta/recipes-devtools/clang/llvm-project-source.inc
@@ -65,18 +65,19 @@  python do_preconfigure() {
     triple = ""
     name = ""
     check = ""
-    oe_names = ""
+    oe_names = []
     distros = d.getVar('CLANG_EXTRA_OE_DISTRO')
     for distro in distros.split():
-        distro_id = distro.split(":")[0].replace('-','_')
+        distro_id_raw = distro.split(":")[0]
+        distro_id = distro_id_raw.replace('-','_')
         distro_triple = distro.split(":")[1]
-        case += '\\n    .Case("' + distro_id + '", Distro::' + distro_id.upper() + ')'
+        case += '\\n    .Case("' + distro_id_raw + '", Distro::' + distro_id.upper() + ')'
         triple += '\\n   if (Distro.Is' + distro_id.upper() + '())\\n     return "x86_64-' + distro_triple + '-linux";'
         name += '\\n    '+ distro_id.upper() + ','
         check += '\\nbool Is' + distro_id.upper() + '() const { return DistroVal == ' + distro_id.upper() + '; }'
-        oe_names +=  distro_id.upper() + ' ||'
+        oe_names.append('DistroVal == ' + distro_id.upper())
 
-    check += '\\nbool IsOpenEmbedded() const { return DistroVal == ' + oe_names[0:-3] + '; }'
+    check += '\\nbool IsOpenEmbedded() const { return ' + ' || '.join(oe_names) + '; }'
 
     cmd = ['sed', '-i', 's#//CLANG_EXTRA_OE_DISTRO_NAME#%s#g' % name, source + '/clang/include/clang/Driver/Distro.h']
     subprocess.check_output(cmd, stderr=subprocess.STDOUT)