From 96e585ec287508736e1b2773e3422e89555c7c8a Mon Sep 17 00:00:00 2001 From: Keith Bennett Date: Sat, 23 Oct 2021 16:08:40 -0500 Subject: [PATCH] Ensure that the rpath is prepended instead of overwritten --- deploy/linux-post-link.sh | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/deploy/linux-post-link.sh b/deploy/linux-post-link.sh index 4824420..7df5cbe 100755 --- a/deploy/linux-post-link.sh +++ b/deploy/linux-post-link.sh @@ -12,7 +12,12 @@ # but they might be a different version. It "might" work, it might cause subtle # bugs, or it might not work at all. # -# To patch the libraries, a tool called `patchelf` is used. +# It's possible there's no current rpath for a particular library. It's also +# possible that the library has other dependencies in its existing rpath. So +# updating the rpath is non-trivial and it's a real shame that qmake doesn't +# do this for us. +# +# To patch the libraries `readelf` and `patchelf` tools are used. # # If the libraries' rpath isn't set correctly then LD_LIBRARY_PATH would need # to be used, like such: @@ -50,16 +55,40 @@ find "${QTDIR}" \ -executable \ 2>/dev/null | while IFS='' read -r library; do + # Get the library's current RPATH (RUNPATH) + # Example output of `readelf readelf -d ./build/build-qgroundcontrol-Desktop_Qt_5_15_2_GCC_64bit-Debug/staging/QGroundControl`: + # 0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN/Qt/libs:/home/kbennett/storage/Qt/5.15.2/gcc_64/lib] + # + # If you find a better way to do this, please fix. + set +o pipefail + current_rpath="$( + # read the library, parsing its header + # search for the RUNPATH field + # filter out the human-readable text to leave only the RUNPATH value + readelf -d "${library}" | + grep -P '^ 0x[0-9a-f]+ +\(RUNPATH\) ' | + sed -r 's/^ 0x[0-9a-f]+ +\(RUNPATH\) +Library runpath: \[(.*)\]$/\1/g' + )" + set -o pipefail + # Get the directory containing the library library_dir="$(dirname "${library}")" # Get the relative path from the library's directory to the Qt/libs directory. - library_rpath="$(realpath --relative-to "${library_dir}" "${RPATHDIR}")" + our_rpath="$(realpath --relative-to "${library_dir}" "${RPATHDIR}")" - # patch the library's rpath to point to the Qt/libs directory. + # Calculate a new rpath with our library's rpath prefixed. # Note: '$ORIGIN' must not be expanded by the shell! # shellcheck disable=SC2016 - patchelf --set-rpath '$ORIGIN/'"${library_rpath}" "${library}" + new_rpath='$ORIGIN/'"${our_rpath}" + + # If the library already had an rpath, then prefix ours to it. + if [ -n "${current_rpath}" ]; then + new_rpath="${new_rpath}:${current_rpath}" + fi + + # patch the library's rpath + patchelf --set-rpath "${new_rpath}" "${library}" done # Create a qt.conf file