diff mbox series

rust: Enable dynamic linking with llvm

Message ID 20260212165035.1806068-1-sunilkumar.dora@windriver.com
State Changes Requested
Headers show
Series rust: Enable dynamic linking with llvm | expand

Commit Message

Dora, Sunil Kumar Feb. 12, 2026, 4:50 p.m. UTC
From: Sunil Dora <sunilkumar.dora@windriver.com>

YOCTO #16058

When llvm-native is built with a newer toolchain (e.g. GCC 15) and
reused on a system with an older linker, rustc emit segfault at runtime.

This issue occurs because rustc, which is statically linked with LLVM libraries,
was built on one machine using a newer toolchain and then executed on another machine
that has an older linker. To prevent crash, LLVM now linked with rustc dynamically.

Added llvm as dependency to provide libllvm.so at runtime.

Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
Signed-off-by: Deepesh Varatharajan <Deepesh.Varatharajan@windriver.com>
---
 meta/lib/oeqa/selftest/cases/rust.py      | 2 +-
 meta/recipes-devtools/rust/rust_1.93.0.bb | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

Comments

Ross Burton Feb. 12, 2026, 5:05 p.m. UTC | #1
On 12 Feb 2026, at 16:50, Dora, Sunil Kumar via lists.openembedded.org <SunilKumar.Dora=windriver.com@lists.openembedded.org> wrote:
> 
> From: Sunil Dora <sunilkumar.dora@windriver.com>
> 
> YOCTO #16058
> 
> When llvm-native is built with a newer toolchain (e.g. GCC 15) and
> reused on a system with an older linker, rustc emit segfault at runtime.
> 
> This issue occurs because rustc, which is statically linked with LLVM libraries,
> was built on one machine using a newer toolchain and then executed on another machine
> that has an older linker. To prevent crash, LLVM now linked with rustc dynamically.
> 

What’s the impact on the native sysroot and target packages when we link rust against all of libLLVM.so dynamically vs statically linking the pieces that are used?

Ross
Alexander Kanavin Feb. 12, 2026, 5:52 p.m. UTC | #2
On Thu, 12 Feb 2026 at 17:51, Dora, Sunil Kumar via
lists.openembedded.org
<SunilKumar.Dora=windriver.com@lists.openembedded.org> wrote:
> This issue occurs because rustc, which is statically linked with LLVM libraries,
> was built on one machine using a newer toolchain and then executed on another machine
> that has an older linker.

I don't think the above is quite accurate? The issue is maybe better
explained step by step:

- llvm-native is built with a newer (e.g. gcc 15/binutils2.45) toolchain
- rust-native is statically linked with parts of llvm-native using an
older toolchain (e.g. binutils 2.40), which does it incorrectly
- rust-native is executed (toolchain is not relevant at this step
anymore), and crashes inside statically linked llvm code

> Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
> Signed-off-by: Alexander Kanavin <alex@linutronix.de>
> Signed-off-by: Deepesh Varatharajan <Deepesh.Varatharajan@windriver.com>

"Signed-off-by:" tags are sensitive. They're like real signatures, in
the sense that you can only add your own, and never other people's
(even if they gave you 'permission' via some side channel). If you
want to acknowledge others, you should do it with an informal tag,
e.g. Suggested-by or Tested-by, or just say "Thanks to Alex for X, and
Deepech for Y".

Alex
Dora, Sunil Kumar Feb. 13, 2026, 7:51 p.m. UTC | #3
On Thu, Feb 12, 2026 at 10:36 PM, Ross Burton wrote:

> 
> What’s the impact on the native sysroot and target packages when we link
> rust against all of libLLVM.so dynamically vs statically linking the
> pieces that are used?

Hi Ross,

Below are the observed impacts when linking Rust against shared libLLVM.so versus
statically linking LLVM components.

On Native:
**********
All required LLVM-related libraries were already present in recipe-sysroot-native before switching
Rust to dynamic LLVM. Dynamic linking does not introduce any new native dependencies.
Existing llvm-native artifacts are reused.

Static:
-rw-r--r-- 1 xxx users 213M Feb 13 00:29 librustc_driver-4b6f2c2478f9ef2c.so
Dynamic:
-rw-r--r-- 1 xxx users 132M Feb 13 00:52 librustc_driver-4b6f2c2478f9ef2c.so

So on native we see ~81 MB reduction in librustc_driver, with no additional sysroot growth.

On Target:
**********
librustc_driver shrinks from 144.8 MB to 84.2 MB (~60 MB reduction).
However, dynamic linking introduces shared libLLVM.so plus a few runtime dependencies.

Static:
root@qemux86-64:~# ls -lh /usr/lib/librustc_driver-*.so
-rw-r--r--    1 root     root      144.8M Apr  5  2011 /usr/lib/librustc_driver-151eed90355bbdac.so

Dynamic:
root@qemux86-64:~# ls -lh /usr/lib/librustc_driver-*.so
-rw-r--r--    1 root     root       84.2M Apr  5  2011 /usr/lib/librustc_driver-151eed90355bbdac.so

New dynamic dependencies:
root@qemux86-64:~# ldd /usr/lib/librustc_driver-*.so
libLLVM.so.21.1 libffi.so.8 libxml2.so.16

Size contribution on target:
- libLLVM.so.21.1 ≈ 75.5 MB
- libxml2.so.16 ≈ 1.2 MB
- libffi.so.8 ≈ 42.5 KB

When LLVM is only used by Rust, this results in a net image increase of approximately 15–16 MB.
Dora, Sunil Kumar Feb. 13, 2026, 7:53 p.m. UTC | #4
Hi Alex,

Thanks for the clarification — you're right, my earlier wording was not precise.
I’ll update the commit message accordingly and resend as v2.

Also, thanks for pointing out the Signed-off-by guidance — I’ll remove the additional tags
and use appropriate acknowledgements instead.
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..cfee48ec78 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 ""):