Since being 'self-contained' is something I care about, I've been bothered for years by an issue where, using a self-built Yocto image with a built-in build appliance, I hit a failure in libcxx-native as soon as TOOLCHAIN = "clang" is used. With the help of claude.ai and a lot of debugging, I put together this patch, which fixes my problem.

On Wed, Aug 12 2026 at 18:13:40 +02:00:00, Markus Volk via lists.openembedded.org <[email protected]> wrote:
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 <[email protected] <mailto:[email protected]>> Co-authored-by: Claude <[email protected] <mailto:[email protected]>>
---
 meta/recipes-devtools/clang/llvm-project-source.inc | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

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)
--
2.55.0





-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#243298): 
https://lists.openembedded.org/g/openembedded-core/message/243298
Mute This Topic: https://lists.openembedded.org/mt/120720284/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to