diff mbox series

llvm-project-source: make do_preconfigure re-entrant

Message ID 20261104224627.1280147-1-ricardo.salveti@oss.qualcomm.com
State New
Headers show
Series llvm-project-source: make do_preconfigure re-entrant | expand

Commit Message

Ricardo Salveti Nov. 4, 2026, 10:46 p.m. UTC
do_preconfigure replaces the //CLANG_EXTRA_OE_* anchors in the shared
source tree with the vendor and distro lists of the current
configuration, consuming the anchors, so it only works on a freshly
patched tree.

When the configuration changes in an existing TMPDIR, for example from
DISTRO=nodistro to a DISTRO with TARGET_VENDOR = "-qcom", do_unpack and
do_patch stay valid and only do_preconfigure re-runs. Its seds find
nothing to replace, so the tree keeps the previous vendor list while
the task hash promises the new one. llvm-native and clang-native are
built from that tree and published to sstate under the new hash, from
where pristine builds of the same configuration restore them. That
clang does not treat aarch64-qcom-linux as an OpenEmbedded vendor,
skips the <sysroot>/usr/lib/<triple>/<version> GCC layout and finds no
libstdc++ headers; mesa's rusticl bindgen fails with "'cstddef' file
not found".

Keep the anchors in place and insert the generated lines before them,
each tagged with a comment naming its anchor, so that a run first
drops what the previous run inserted. The task can now run any number
of times, with any configuration, and always leaves the tree that
configuration describes, as suggested when adding vardeps was proposed
instead [1]. The generated code is unchanged apart from whitespace and
the tags; an empty CLANG_EXTRA_OE_DISTRO now yields an IsOpenEmbedded()
that returns false instead of invalid C++.

Move the Gnu.cpp anchor onto a line of its own like the others. The
changed patch also makes existing build directories, whose tree has
already lost its anchors, unpack and patch the sources again.

[1] https://patchwork.yoctoproject.org/project/oe-core/patch/20260623120818.110754-5-joaomarcos.costa@bootlin.com/

Assisted-by: Claude Code:claude-fable-5-1
Signed-off-by: Ricardo Salveti <ricardo.salveti@oss.qualcomm.com>
---
 ...t-anchor-for-adding-OE-distro-vendor.patch | 11 +--
 .../clang/llvm-project-source.inc             | 83 ++++++++++---------
 2 files changed, 50 insertions(+), 44 deletions(-)
diff mbox series

Patch

diff --git a/meta/recipes-devtools/clang/clang/0013-llvm-clang-Insert-anchor-for-adding-OE-distro-vendor.patch b/meta/recipes-devtools/clang/clang/0013-llvm-clang-Insert-anchor-for-adding-OE-distro-vendor.patch
index aba7488323..b7c8b8e536 100644
--- a/meta/recipes-devtools/clang/clang/0013-llvm-clang-Insert-anchor-for-adding-OE-distro-vendor.patch
+++ b/meta/recipes-devtools/clang/clang/0013-llvm-clang-Insert-anchor-for-adding-OE-distro-vendor.patch
@@ -98,10 +98,10 @@  Signed-off-by: João Marcos Costa <joaomarcos.costa@bootlin.com>
 ---
  clang/include/clang/Driver/Distro.h   | 2 ++
  clang/lib/Driver/Distro.cpp           | 1 +
- clang/lib/Driver/ToolChains/Gnu.cpp   | 1 +
+ clang/lib/Driver/ToolChains/Gnu.cpp   | 2 ++
  clang/lib/Driver/ToolChains/Linux.cpp | 2 ++
  llvm/lib/TargetParser/Triple.cpp      | 1 +
- 5 files changed, 7 insertions(+)
+ 5 files changed, 8 insertions(+)
 
 diff --git a/clang/include/clang/Driver/Distro.h b/clang/include/clang/Driver/Distro.h
 index aa4b3e1..2d77a2b 100644
@@ -136,14 +136,15 @@  index 585497e..3b58ac7 100644
    return Version;
  }
 diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
-index f44663f..73ff1f4 100644
+index dfb0390..82a3bac 100644
 --- a/clang/lib/Driver/ToolChains/Gnu.cpp
 +++ b/clang/lib/Driver/ToolChains/Gnu.cpp
-@@ -2371,6 +2371,7 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
+@@ -2383,6 +2383,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
        "x86_64-pc-linux-gnu",    "x86_64-redhat-linux6E",
        "x86_64-redhat-linux",    "x86_64-suse-linux",
        "x86_64-manbo-linux-gnu", "x86_64-slackware-linux",
-+      "x86_64-oe-linux",//CLANG_EXTRA_OE_VENDORS_TRIPLES
++      "x86_64-oe-linux",
++      //CLANG_EXTRA_OE_VENDORS_TRIPLES
        "x86_64-unknown-linux",   "x86_64-amazon-linux"};
    static const char *const X32Triples[] = {"x86_64-linux-gnux32",
                                             "x86_64-pc-linux-gnux32"};
diff --git a/meta/recipes-devtools/clang/llvm-project-source.inc b/meta/recipes-devtools/clang/llvm-project-source.inc
index 5cd08d4085..370fbc493d 100644
--- a/meta/recipes-devtools/clang/llvm-project-source.inc
+++ b/meta/recipes-devtools/clang/llvm-project-source.inc
@@ -31,14 +31,30 @@  CLANG_EXTRA_OE_DISTRO ?= "poky:poky"
 # Match with MULTILIB_GLOBAL_VARIANTS
 ML_VARIANTS = "lib32 lib64 libx32"
 
+# Insert lines before the //<anchor> comment in path. The anchor stays in
+# place and every inserted line carries a comment naming it, so a later run
+# of do_preconfigure on the same shared tree first drops what the previous
+# run inserted: the result only depends on the current configuration.
+def clang_oe_generate(path, anchor, lines):
+    anchor_comment = "//" + anchor
+    marker = "// do_preconfigure: " + anchor
+    with open(path) as f:
+        content = [line for line in f.read().split("\n") if not line.rstrip().endswith(marker)]
+    anchors = [i for i, line in enumerate(content) if line.rstrip().endswith(anchor_comment)]
+    if len(anchors) != 1:
+        bb.fatal("Expected one %s anchor in %s, found %d" % (anchor_comment, path, len(anchors)))
+    i = anchors[0]
+    indent = content[i][:len(content[i]) - len(content[i].lstrip())]
+    content[i:i] = [indent + line + " " + marker for line in lines]
+    with open(path, "w") as f:
+        f.write("\n".join(content))
+
 python do_preconfigure() {
-    import subprocess
-    case = ""
-    triple = ""
-    vendors = d.getVar('CLANG_EXTRA_OE_VENDORS')
+    source = d.getVar("S")
     multilib_variants = (d.getVar("ML_VARIANTS") or "").split()
+
     vendors_to_add = []
-    for vendor in vendors.split():
+    for vendor in (d.getVar('CLANG_EXTRA_OE_VENDORS') or "").split():
         # convert -yoe into yoe
         vendor = vendor.lstrip('-')
         # generate possible multilib vendor names for yoe
@@ -48,45 +64,34 @@  python do_preconfigure() {
         if vendor != "oe":
             vendors_to_add.append(vendor)
 
-    for vendor_to_add in vendors_to_add:
-        case += '\\n    .Case("' + vendor_to_add + '", Triple::OpenEmbedded)'
-        triple += ' "x86_64-' + vendor_to_add + '-linux",'
-
     bb.note("Adding support following TARGET_VENDOR values")
     bb.note(str(vendors_to_add))
     bb.note("in llvm/lib/TargetParser/Triple.cpp and ${S}/clang/lib/Driver/ToolChains/Gnu.cpp")
-    source = d.getVar("S")
-    cmd = ['sed', '-i', 's#//CLANG_EXTRA_OE_VENDORS_TRIPLES#%s#g' % triple, source + '/clang/lib/Driver/ToolChains/Gnu.cpp']
-    subprocess.check_output(cmd, stderr=subprocess.STDOUT)
-    cmd = ['sed', '-i', 's#//CLANG_EXTRA_OE_VENDORS_CASES#%s#g' % case, source + '/llvm/lib/TargetParser/Triple.cpp']
-    subprocess.check_output(cmd, stderr=subprocess.STDOUT)
-
-    case = ""
-    triple = ""
-    name = ""
-    check = ""
-    oe_names = []
-    distros = d.getVar('CLANG_EXTRA_OE_DISTRO')
-    for distro in distros.split():
-        distro_id_raw = distro.split(":")[0]
-        distro_id = distro_id_raw.replace('-','_')
-        distro_triple = distro.split(":")[1]
-        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.append('DistroVal == ' + distro_id.upper())
+    clang_oe_generate(source + '/llvm/lib/TargetParser/Triple.cpp', 'CLANG_EXTRA_OE_VENDORS_CASES',
+                      ['.Case("%s", Triple::OpenEmbedded)' % v for v in vendors_to_add])
+    clang_oe_generate(source + '/clang/lib/Driver/ToolChains/Gnu.cpp', 'CLANG_EXTRA_OE_VENDORS_TRIPLES',
+                      ['"x86_64-%s-linux",' % v for v in vendors_to_add])
 
-    check += '\\nbool IsOpenEmbedded() const { return ' + ' || '.join(oe_names) + '; }'
+    names = []
+    checks = []
+    cases = []
+    triples = []
+    oe_checks = []
+    for distro in (d.getVar('CLANG_EXTRA_OE_DISTRO') or "").split():
+        distro_id, distro_triple = distro.split(":")
+        # the ID doubles as a C++ enumerator name
+        enum = distro_id.replace('-', '_').upper()
+        names.append(enum + ",")
+        checks.append("bool Is%s() const { return DistroVal == %s; }" % (enum, enum))
+        cases.append('.Case("%s", Distro::%s)' % (distro_id, enum))
+        triples.append('if (Distro.Is%s()) return "x86_64-%s-linux";' % (enum, distro_triple))
+        oe_checks.append("DistroVal == " + enum)
+    checks.append("bool IsOpenEmbedded() const { return %s; }" % (" || ".join(oe_checks) or "false"))
 
-    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)
-    cmd = ['sed', '-i', 's#//CLANG_EXTRA_OE_DISTRO_CHECK#%s#g' % check, source + '/clang/include/clang/Driver/Distro.h']
-    subprocess.check_output(cmd, stderr=subprocess.STDOUT)
-    cmd = ['sed', '-i', 's#//CLANG_EXTRA_OE_DISTRO_TRIPLE#%s#g' % triple, source + '/clang/lib/Driver/ToolChains/Linux.cpp']
-    subprocess.check_output(cmd, stderr=subprocess.STDOUT)
-    cmd = ['sed', '-i', 's#//CLANG_EXTRA_OE_DISTRO_CASE#%s#g' % case, source + '/clang/lib/Driver/Distro.cpp']
-    subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+    clang_oe_generate(source + '/clang/include/clang/Driver/Distro.h', 'CLANG_EXTRA_OE_DISTRO_NAME', names)
+    clang_oe_generate(source + '/clang/include/clang/Driver/Distro.h', 'CLANG_EXTRA_OE_DISTRO_CHECK', checks)
+    clang_oe_generate(source + '/clang/lib/Driver/Distro.cpp', 'CLANG_EXTRA_OE_DISTRO_CASE', cases)
+    clang_oe_generate(source + '/clang/lib/Driver/ToolChains/Linux.cpp', 'CLANG_EXTRA_OE_DISTRO_TRIPLE', triples)
 }
 
 do_patch[vardepsexclude] += "MULTILIBS MULTILIB_VARIANTS"