diff mbox series

llvm/rust: simplify llvm-config handling for target builds

Message ID 20260609141916.2724362-1-Deepesh.Varatharajan@windriver.com
State Changes Requested
Headers show
Series llvm/rust: simplify llvm-config handling for target builds | expand

Commit Message

Varatharajan, Deepesh June 9, 2026, 2:19 p.m. UTC
From: Deepesh Varatharajan <Deepesh.Varatharajan@windriver.com>

Replace PATH-based llvm-config discovery with explicit sysroot-native
resolution and simplify the target llvm-config wrapper to act as a pure
pass-through while preserving Yocto alternate path handling.

The previous implementation relied on:

* `which -a llvm-config | sed -n 2p`

  This depends on PATH ordering and assumes the desired native
  llvm-config is visible in the build environment. In cross-build
  configurations this is fragile and may resolve an unexpected
  instance or fail to locate the intended tool.

* `echo $base_libdir | sed -n '/lib64/p'`

  This depends on build-time variable expansion and may select an
  incorrect library directory when the expected value is unavailable.

Update the wrapper to:

* Resolve llvm-config directly from known sysroot-native location.
* Detect libdir using filesystem inspection rather than variable
  parsing.
* Preserve `YOCTO_ALTERNATE_EXE_PATH` and
  `YOCTO_ALTERNATE_LIBDIR` handling.
* Delegate all arguments directly to the native llvm-config.

Remove the native llvm-config copy logic and lib/lib64 symlink workaround.

Signed-off-by: Deepesh Varatharajan <Deepesh.Varatharajan@windriver.com>
---
 ...unwind.pc.in-and-llvm-config-scripts.patch | 52 +++----------------
 meta/recipes-devtools/rust/rust_1.96.0.bb     | 41 +--------------
 2 files changed, 9 insertions(+), 84 deletions(-)

Comments

Varatharajan, Deepesh June 9, 2026, 2:22 p.m. UTC | #1
Hi All,

Tested the patch with the following builds and all completed successfully:

rust
clang
mesa
--with multilibs enabled

The changes correctly resolve llvm-config from the native sysroot, eliminate the need for the previous llvm-config copy/symlink workarounds, and work correctly with multilib (lib64) configurations.

Regards,
Deepesh
Richard Purdie June 9, 2026, 9:22 p.m. UTC | #2
Hi Deepesh,

On Tue, 2026-06-09 at 07:22 -0700, Varatharajan, Deepesh via lists.openembedded.org wrote:
> Tested the patch with the following builds and all completed
> successfully:
> 
> rust
> clang
> mesa
>    --with multilibs enabled
> 
> The changes correctly resolve llvm-config from the native sysroot,
> eliminate the need for the previous llvm-config copy/symlink
> workarounds, and work correctly with multilib (lib64) configurations.

Did you test this on non-x86?

I ran this through the autobuilder and there was a lot of red:

https://autobuilder.yoctoproject.org/valkyrie/#/builders/29/builds/3956

much of which look related to this change :(

Cheers,

Richard
Varatharajan, Deepesh June 10, 2026, 5:12 a.m. UTC | #3
On 10-06-2026 02:52, Richard Purdie wrote:
> CAUTION: This email comes from a non Wind River email account!
> Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
> Hi Deepesh,
>
> On Tue, 2026-06-09 at 07:22 -0700, Varatharajan, Deepesh via lists.openembedded.org wrote:
>> Tested the patch with the following builds and all completed
>> successfully:
>>
>> rust
>> clang
>> mesa
>>     --with multilibs enabled
>>
>> The changes correctly resolve llvm-config from the native sysroot,
>> eliminate the need for the previous llvm-config copy/symlink
>> workarounds, and work correctly with multilib (lib64) configurations.
> Did you test this on non-x86?
Hi Richard,

Yes, I did. The failures reported by the autobuilder are limited to the 
nativesdk builds.
The target builds completed successfully across all architectures.
>
> I ran this through the autobuilder and there was a lot of red:
>
> https://autobuilder.yoctoproject.org/valkyrie/#/builders/29/builds/3956
>
> much of which look related to this change :(

The failures were traced back to two tasks:
nativesdk-rust:do_compile
nativesdk-mesa:do_configure.

Both issues have now been addressed. I'll complete some additional 
testing and
then send a V2.

Regards,
Deepesh

>
> Cheers,
>
> Richard
diff mbox series

Patch

diff --git a/meta/recipes-devtools/clang/clang/0026-llvm-Add-libunwind.pc.in-and-llvm-config-scripts.patch b/meta/recipes-devtools/clang/clang/0026-llvm-Add-libunwind.pc.in-and-llvm-config-scripts.patch
index eeb802732b..a2c3532a66 100644
--- a/meta/recipes-devtools/clang/clang/0026-llvm-Add-libunwind.pc.in-and-llvm-config-scripts.patch
+++ b/meta/recipes-devtools/clang/clang/0026-llvm-Add-libunwind.pc.in-and-llvm-config-scripts.patch
@@ -8,6 +8,7 @@  These are added by OE project
 Upstream-Status: Inappropriate [ OE-Specific ]
 
 Signed-off-by: Khem Raj <raj.khem@gmail.com>
+Signed-off-by: Deepesh Varatharajan <Deepesh.Varatharajan@windriver.com>
 ---
  libunwind/libunwind.pc.in          |  9 ++++++
  llvm/tools/llvm-config/llvm-config | 52 ++++++++++++++++++++++++++++++
@@ -35,56 +36,19 @@  new file mode 100644
 index 000000000000..6a0dd54b8eab
 --- /dev/null
 +++ b/llvm/tools/llvm-config/llvm-config
-@@ -0,0 +1,52 @@
+@@ -0,0 +1,15 @@
 +#!/bin/bash
 +#
-+# Wrapper script for llvm-config. Supplies the right environment variables
-+# for the target and delegates to the native llvm-config for anything else. This
-+# is needed because arguments like --ldflags, --cxxflags, etc. are set by the
-+# native compile rather than the target compile.
++#The llvm-config wrapper will act as a pure pass-through to the native llvm-config
++#while preserving Yocto-specific environment variables used for alternate executable
++#and library path resolution.
 +#
 +SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
-+NEXT_LLVM_CONFIG="$(which -a llvm-config | sed -n 2p)"
++NEXT_LLVM_CONFIG="$(readlink -f "$SCRIPT_DIR/../../../../recipe-sysroot-native/usr/bin/llvm-config")"
 +export YOCTO_ALTERNATE_EXE_PATH="${YOCTO_ALTERNATE_EXE_PATH:="$(readlink -f "$SCRIPT_DIR/../llvm-config")"}"
-+if [ -n "$( echo $base_libdir | sed -n '/lib64/p')" ]; then
++if [ -d "$(readlink -f "$SCRIPT_DIR/../../lib64")" ]; then
 +    export YOCTO_ALTERNATE_LIBDIR="${YOCTO_ALTERNATE_LIBDIR:="/lib64"}"
 +else
 +    export YOCTO_ALTERNATE_LIBDIR="${YOCTO_ALTERNATE_LIBDIR:="/lib"}"
 +fi
-+if [[ $# == 0 ]]; then
-+  exec "$NEXT_LLVM_CONFIG"
-+fi
-+
-+remain=""
-+output=""
-+for arg in "$@"; do
-+  case "$arg" in
-+    --cppflags)
-+      output="${output} ${CPPFLAGS}"
-+      ;;
-+    --cflags)
-+      output="${output} ${CFLAGS}"
-+      ;;
-+    --cxxflags)
-+      output="${output} ${CXXFLAGS}"
-+      ;;
-+    --ldflags)
-+      output="${output} ${LDFLAGS}"
-+      ;;
-+    --shared-mode)
-+      output="${output} shared"
-+      ;;
-+    --link-shared)
-+      break
-+      ;;
-+    *)
-+      remain="${remain} ${arg}"
-+      ;;
-+  esac
-+done
-+
-+if [ "${remain}" != "" ]; then
-+      output="${output} "$("$NEXT_LLVM_CONFIG" ${remain})
-+fi
-+
-+echo "${output}"
++exec "$NEXT_LLVM_CONFIG" "$@"
diff --git a/meta/recipes-devtools/rust/rust_1.96.0.bb b/meta/recipes-devtools/rust/rust_1.96.0.bb
index 3eb2a36406..45a67e71ab 100644
--- a/meta/recipes-devtools/rust/rust_1.96.0.bb
+++ b/meta/recipes-devtools/rust/rust_1.96.0.bb
@@ -31,7 +31,7 @@  PV .= "${@bb.utils.contains('RUST_CHANNEL', 'stable', '', '-${RUST_CHANNEL}', d)
 
 export FORCE_CRATE_HASH = "${BB_TASKHASH}"
 
-RUST_ALTERNATE_EXE_PATH ?= "${STAGING_BINDIR}/llvm-config"
+RUST_ALTERNATE_EXE_PATH ?= "${STAGING_BINDIR_CROSS}/llvm-config"
 RUST_ALTERNATE_EXE_PATH_NATIVE = "${STAGING_BINDIR_NATIVE}/llvm-config"
 
 # We don't want to use bitbakes vendoring because the rust sources do their
@@ -192,37 +192,6 @@  python do_configure() {
     bb.build.exec_func("setup_cargo_environment", d)
 }
 
-# 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'
-do_compile:append:class-target() {
-    # Ensure llvm-config can find static libraries in multilib setup
-    lib64_dir="${STAGING_DIR_TARGET}/usr/lib64"
-    lib_dir="${STAGING_DIR_TARGET}/usr/lib"
-
-    if [ -d "$lib64_dir" ]; then
-        # If lib does not exist, symlink it to lib64
-        if [ ! -e "$lib_dir" ]; then
-            ln -s lib64 "$lib_dir"
-        fi
-
-        # 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 "${lib64_dir}"/libLLVM*.so*; do
-                if [ -e "$lib64_file" ]; then
-                    lib_name=$(basename "${lib64_file}")
-                    target_link="${lib_dir}/${lib_name}"
-
-                    if [ ! -e "${target_link}" ]; then
-                        ln -s "../lib64/${lib_name}" "${target_link}"
-                    fi
-                fi
-            done
-        fi
-    fi
-}
-
 rust_runx () {
     echo "COMPILE ${PN}" "$@"
 
@@ -236,14 +205,6 @@  rust_runx () {
 
     export RUSTFLAGS="${RUST_DEBUG_REMAP} -Clink-arg=-lz -Clink-arg=-lzstd"
 
-    # Copy the natively built llvm-config into the target so we can run it. Horrible,
-    # but works!
-    if [ ${RUST_ALTERNATE_EXE_PATH_NATIVE} != ${RUST_ALTERNATE_EXE_PATH} -a ! -f ${RUST_ALTERNATE_EXE_PATH} ]; then
-        mkdir -p `dirname ${RUST_ALTERNATE_EXE_PATH}`
-        cp ${RUST_ALTERNATE_EXE_PATH_NATIVE} ${RUST_ALTERNATE_EXE_PATH}
-        patchelf --remove-rpath ${RUST_ALTERNATE_EXE_PATH}
-    fi
-
     oe_cargo_fix_env
 
     python3 src/bootstrap/bootstrap.py ${@oe.utils.parallel_make_argument(d, '-j %d')} "$@" --verbose