mirror of
https://git.yoctoproject.org/poky
synced 2026-03-17 04:39:40 +01:00
icecc-create-env: Fix executable rpaths
Executables in the toolchain archive occasionally contain runtime library search paths (RPATH) that use the $ORIGIN placeholder. However, in order for that placeholder to work, /proc must be mounted. When iceccd executes the toolchain in the chroot environment, it doesn't mount /proc, so it is unable to resolve $ORIGIN resulting in a failure to find dynamic libraries. The fix is to replace $ORIGIN in executable RPATH entries with the known chroot executable path. In order for this to work, the actual real path to the executable must be resolved to remove any symlinks, otherwise the calculate $ORIGIN replacement will be wrong. This is done by using "readlink -f", which is an acceptable dependency because Yocto already requires it. (From OE-Core rev: cfe98765b40c28a132b5a4bce39f71f06b4eb0bc) Signed-off-by: Joshua Watt <JPEWhacker@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
8a229332a0
commit
971a3c0e2a
@@ -12,6 +12,26 @@ is_dynamic_elf ()
|
||||
(file -L "$1" | grep 'ELF' > /dev/null 2>&1) && (! file -L "$1" | grep 'static' > /dev/null 2>&1)
|
||||
}
|
||||
|
||||
fix_rpath ()
|
||||
{
|
||||
# Patches the RPATH for a file. When the program is executed in the chroot
|
||||
# be iceccd, /proc is not mounted. As such, $ORIGIN can't be resolved. To
|
||||
# work around this, replace all instances of $ORIGIN in RPATH with the
|
||||
# known chroot path to the executables directory
|
||||
local path="$1"
|
||||
local origin="$2"
|
||||
if ! is_dynamic_elf "$path"; then
|
||||
return
|
||||
fi
|
||||
local new_rpath="`readelf -w -d "$path" | grep RPATH | \
|
||||
sed 's/.*\[\(.*\)\]/\1/g' | \
|
||||
sed "s,\\\$ORIGIN,/$origin,g"`"
|
||||
|
||||
if test -n "$new_rpath"; then
|
||||
$PATCHELF --set-rpath "$new_rpath" "$path"
|
||||
fi
|
||||
}
|
||||
|
||||
is_contained ()
|
||||
{
|
||||
case " $target_files " in
|
||||
@@ -47,9 +67,8 @@ add_file ()
|
||||
name="$2"
|
||||
fi
|
||||
test -z "$name" && return
|
||||
# ls -H isn't really the same as readlink, but
|
||||
# readlink is not portable enough.
|
||||
path=`ls -H $path`
|
||||
# readlink is required for Yocto, so we can use it
|
||||
path=`readlink -f "$path"`
|
||||
toadd="$name=$path"
|
||||
is_contained "$toadd" && return
|
||||
if test -z "$silent"; then
|
||||
@@ -108,6 +127,17 @@ added_as=$1
|
||||
shift
|
||||
archive_name=$1
|
||||
|
||||
if test -z "$PATCHELF"; then
|
||||
PATCHELF=`which patchelf 2> /dev/null`
|
||||
fi
|
||||
if test -z "$PATCHELF"; then
|
||||
PATCHELF=`which patchelf-uninative 2> /dev/null`
|
||||
fi
|
||||
if test -z "$PATCHELF"; then
|
||||
echo "patchelf is required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$added_gcc" || test -z "$added_gxx" ; then
|
||||
echo "usage: $0 <gcc_path> <g++_path>"
|
||||
exit 1
|
||||
@@ -197,6 +227,8 @@ for i in $target_files; do
|
||||
if test -f $tempdir/$target -a -x $tempdir/$target; then
|
||||
strip -s $tempdir/$target 2>/dev/null
|
||||
fi
|
||||
|
||||
fix_rpath $tempdir/$target `dirname $target`
|
||||
else
|
||||
mkdir -p $tempdir/`dirname $path`
|
||||
cp -pH $path $tempdir/$path
|
||||
@@ -210,6 +242,8 @@ for i in $target_files; do
|
||||
strip -s $tempdir/$path 2>/dev/null
|
||||
fi
|
||||
|
||||
fix_rpath $tempdir/$path `dirname $path`
|
||||
|
||||
path=`echo $path | cut -b2-`
|
||||
new_target_files="$new_target_files $path"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user