| Message ID | 20260612034643.3215188-1-Deepesh.Varatharajan@windriver.com |
|---|---|
| State | Under Review |
| Headers | show |
| Series | [v3] llvm/mesa/rust: simplify llvm-config handling | expand |
On Thu, 2026-06-11 at 20:46 -0700, Deepesh.Varatharajan@windriver.com wrote: > 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` > which is unreliable in cross-build environments because it only > searches executables present in $PATH. Native sysroot tools > (e.g. recipe-sysroot-native llvm-config) are not guaranteed to be > exposed via PATH, so they may not be discovered at all. We always configure PATH to contain the cross scripts and native sysroot. Is there something which is reconfiguring PATH to skip the native sysroot? > * `echo $base_libdir | sed -n '/lib64/p'` > which depends on a BitBake variable that may be empty or unset > in certain build contexts, leading to incorrect libdir selection. > > Update the wrapper to: > > * Use an @LLVM_CONFIG_PATH@ placeholder that is replaced during the > build with the appropriate native llvm-config path. > * 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. > > Update rust and mesa recipes to replace the placeholder with the native > llvm-config path during target and nativesdk builds. > > Also remove the native llvm-config copy logic and lib/lib64 symlink > workarounds, relying instead on explicit native tool resolution. > > 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 | 52 ++++++------------- > meta/recipes-graphics/mesa/mesa.inc | 16 ++++++ > 3 files changed, 39 insertions(+), 81 deletions(-) > > 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..72ffdc6c1f 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="@LLVM_CONFIG_PATH@" As I understand it, this is always being configured to point at the llvm-config in the native sysroot? I think this script is only ever installed into STAGING_BINDIR_CROSS? If that is the case, could we just set this to a relative path to SCRIPT_DIR, which would then always point at the right places without needing to be adjusted each time? > +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}" > -+ ;; Can you remind me, how does the native llvm-config provide the target cflags? Is that triggered by setting the YOCTO_ALTERNATE_LIBDIR above? Cheers, Richard
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..72ffdc6c1f 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="@LLVM_CONFIG_PATH@" +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..8b0f1d1459 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,22 @@ 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 +replace_llvm_config_path() { + if [ -f "${STAGING_BINDIR_CROSS}/llvm-config" ]; then + sed -i \ + 's#@LLVM_CONFIG_PATH@#${RUST_ALTERNATE_EXE_PATH_NATIVE}#g' \ + ${RUST_ALTERNATE_EXE_PATH} fi } +do_compile:append:class-target() { + replace_llvm_config_path +} + +do_compile:append:class-nativesdk() { + replace_llvm_config_path +} + rust_runx () { echo "COMPILE ${PN}" "$@" @@ -236,14 +221,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 @@ -263,6 +240,7 @@ do_compile () { do_test_compile[dirs] = "${B}" do_test_compile () { + replace_llvm_config_path rust_runx build src/tools/remote-test-server --target "${RUST_TARGET_SYS}" } diff --git a/meta/recipes-graphics/mesa/mesa.inc b/meta/recipes-graphics/mesa/mesa.inc index 15dad6eedd..f40fed5ebc 100644 --- a/meta/recipes-graphics/mesa/mesa.inc +++ b/meta/recipes-graphics/mesa/mesa.inc @@ -51,6 +51,22 @@ ANY_OF_DISTRO_FEATURES = "opencl opengl vulkan" PLATFORMS ??= "${@bb.utils.filter('PACKAGECONFIG', 'x11 wayland', d)}" +replace_llvm_config_path() { + if [ -f "${STAGING_BINDIR_CROSS}/llvm-config" ]; then + sed -i \ + 's#@LLVM_CONFIG_PATH@#${STAGING_BINDIR_NATIVE}/llvm-config#g' \ + ${STAGING_BINDIR_CROSS}/llvm-config + fi +} + +do_configure:prepend:class-target() { + replace_llvm_config_path +} + +do_configure:prepend:class-nativesdk() { + replace_llvm_config_path +} + # set the MESA_BUILD_TYPE to either 'release' (default) or 'debug' # by default the upstream mesa sources build a debug release # here we assume the user will want a release build by default