diff mbox series

[v2] rust: Enable dynamic linking with llvm

Message ID 20260217131636.3155022-1-sunilkumar.dora@windriver.com
State Under Review
Headers show
Series [v2] rust: Enable dynamic linking with llvm | expand

Commit Message

Dora, Sunil Kumar Feb. 17, 2026, 1:16 p.m. UTC
From: Sunil Dora <sunilkumar.dora@windriver.com>

Fixes [Yocto #16058]

A segmentation fault occurs in rustc (e.g. in
llvm::X86ReadAdvanceTable) when reusing sstate artifacts built with
different host toolchain versions.

Issue sequence:
1. llvm-native is built with a newer toolchain
   (e.g. GCC 15/Binutils 2.45).
2. rust-native is later built with an older linker.
   (e.g. GCC 12/Binutils 2.40).
3. The older linker statically links parts of llvm-native into
   librustc_driver.
4. The resulting binary crashes at runtime inside the statically
   linked LLVM code.

The corruption happens at link time when mixing static native objects
produced by different toolchain generations.

Enabling dynamic linking ('link-shared = true') resolves this by linking against
libLLVM.so instead of static archives, avoiding the linker incompatibility entirely.

As rustc now depends on libLLVM.so at runtime, the following changes were made:
 - Added llvm as runtime dependency (for selftest).
 - Extend the multilib symlink handling to include shared libraries so llvm-config
   can locate libLLVM.so in the expected lib directory.

Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
Suggested-by: Alexander Kanavin <alex@linutronix.de>
---
 meta/lib/oeqa/selftest/cases/rust.py      | 2 +-
 meta/recipes-devtools/rust/rust_1.93.0.bb | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/meta/lib/oeqa/selftest/cases/rust.py b/meta/lib/oeqa/selftest/cases/rust.py
index 3ae1946e43..7614941661 100644
--- a/meta/lib/oeqa/selftest/cases/rust.py
+++ b/meta/lib/oeqa/selftest/cases/rust.py
@@ -47,7 +47,7 @@  class RustSelfTestSystemEmulated(OESelftestTestCase, OEPTestResultTestCase):
         bitbake("{} -c test_compile".format(recipe))
         builddir = get_bb_var("RUSTSRC", "rust")
         # build core-image-minimal with required packages
-        default_installed_packages = ["libgcc", "libstdc++", "libatomic", "libgomp", "libzstd", "openssl"]
+        default_installed_packages = ["libgcc", "libstdc++", "libatomic", "libgomp", "libzstd", "llvm", "openssl"]
         features = []
         features.append('IMAGE_FEATURES += "ssh-server-dropbear"')
         features.append('CORE_IMAGE_EXTRA_INSTALL += "{0}"'.format(" ".join(default_installed_packages)))
diff --git a/meta/recipes-devtools/rust/rust_1.93.0.bb b/meta/recipes-devtools/rust/rust_1.93.0.bb
index a25f65f674..e02e7f4b24 100644
--- a/meta/recipes-devtools/rust/rust_1.93.0.bb
+++ b/meta/recipes-devtools/rust/rust_1.93.0.bb
@@ -124,6 +124,7 @@  python do_configure() {
 
     # [llvm]
     config.add_section("llvm")
+    config.set("llvm", "link-shared", e(True))
     config.set("llvm", "static-libstdcpp", e(False))
     config.set("llvm", "download-ci-llvm", e(False))
     if "llvm" in (d.getVar('TC_CXX_RUNTIME') or ""):
@@ -188,7 +189,7 @@  python do_configure() {
     bb.build.exec_func("setup_cargo_environment", d)
 }
 
-# llvm-config expects static libraries to be in the 'lib' directory rather than 'lib64' when
+# llvm-config expects static/dynamic libraries to be in the 'lib' directory rather than 'lib64' when
 # multilibs enabled. Since we are copying the natively built llvm-config into the target sysroot
 # and executing it there, it will default to searching in 'lib', as it is unaware of the 'lib64'
 # directory. To ensure llvm-config can locate the necessary libraries, create a symlink from 'lib'
@@ -205,7 +206,7 @@  do_compile:append:class-target() {
 
         # Only do per-file symlinking if lib is a real directory (not symlink)
         if [ -d "$lib_dir" ] && [ ! -L "$lib_dir" ]; then
-            for lib64_file in "${lib64_dir}"/libLLVM*.a; do
+            for lib64_file in "${lib64_dir}"/libLLVM*.a "${lib64_dir}"/libLLVM*.so*; do
                 if [ -e "$lib64_file" ]; then
                     lib_name=$(basename "${lib64_file}")
                     target_link="${lib_dir}/${lib_name}"