abuild: only scan /lib /usr/lib, $rpath and $ldpath for provides

This is to avoid scan dlopen'ed plugins.

We scan any rpath set by any subpackage from same apkbuild. If it depends
on rpath to other package, developer will have to add that to ldpath.

This change means we have to move generation of .provides-so and .needs-so
til after all .rpaths are generated.
This commit is contained in:
Natanael Copa 2012-09-06 13:00:54 +00:00
parent 14af6a80cf
commit c6b7fa8a6a
1 changed files with 78 additions and 34 deletions

112
abuild.in
View File

@ -778,33 +778,10 @@ prepare_tracedeps() {
local etype= soname= file= sover= local etype= soname= file= sover=
[ "$arch" = "noarch" ] && return 0 [ "$arch" = "noarch" ] && return 0
options_has "!tracedeps" && return 0 options_has "!tracedeps" && return 0
# lets tell all the .so files this package provides in .provides-so
scanelf --recursive --nobanner --soname "$dir" | while read etype soname file; do
# if soname field is missing, soname will be the filepath
# we only want shared libs
sover=0
case $soname in
*.so|*.so.[0-9]*)
soname=${soname##*/}
case "$file" in
*.so.[0-9]*) sover=${file##*.so.};;
esac
echo "$soname $sover"
;;
esac
done >"$controldir"/.provides-so
# lets tell all the places we should look for .so files - all rpaths # lets tell all the places we should look for .so files - all rpaths
scanelf -q -Rr "$dir" | sed -e 's/[[:space:]].*//' -e 's/:/\n/' \ scanelf --quiet --recursive --rpath "$dir" \
| sort | uniq \ | sed -e 's/[[:space:]].*//' -e 's/:/\n/' | sort -u \
>"$controldir"/.rpaths >"$controldir"/.rpaths
# now find the so dependencies
scanelf -Rn "$dir" | tr ' ' ':' | awk -F ":" '$1 == "ET_DYN" || $1 == "ET_EXEC" {print $2}' \
| sed 's:,:\n:g' | sort | uniq \
| while read i; do
# only add files that are not self provided
grep -q -w "^$i" "$controldir"/.provides-so \
|| echo $i >> "$controldir"/.needs-so
done
} }
# check if dir has arch specific binaries # check if dir has arch specific binaries
@ -878,7 +855,7 @@ trace_apk_deps() {
local name="$1" local name="$1"
local dir="$2" local dir="$2"
local i= j= found= autodeps= deppkgs= missing= so_paths= self_provided= local i= j= found= autodeps= deppkgs= missing= so_paths= self_provided=
msg "Tracing dependencies for $name..." msg "Tracing dependencies..."
# add pkgconfig if usr/lib/pkgconfig is found # add pkgconfig if usr/lib/pkgconfig is found
if [ -d "$pkgbasedir"/$name/usr/lib/pkgconfig ] \ if [ -d "$pkgbasedir"/$name/usr/lib/pkgconfig ] \
&& ! grep -q '^depend = pkgconfig' "$dir"/.PKGINFO; then && ! grep -q '^depend = pkgconfig' "$dir"/.PKGINFO; then
@ -938,19 +915,83 @@ trace_apk_deps() {
done done
} }
find_scanelf_paths() {
local controldir="$1" datadir="$2"
local paths="$datadir/lib:$datadir/usr/lib" i= rpath=
if [ -n "$ldpath" ]; then
paths="$paths:$ldpath"
fi
# search in all rpaths
for rpath in "$pkgbasedir"/.control.*/.rpath; do
[ -f "$rpath" ] || continue
while read i; do
if [ -d "$datadir/$i" ]; then
paths="$paths:$datadir/$i"
fi
done < "$rpath"
done
echo "$paths"
}
scan_shared_objects() {
local name="$1" controldir="$2" datadir="$3"
# allow spaces in paths
IFS=:
set -- $(find_scanelf_paths "$controldir" "$datadir")
unset IFS
msg "Scanning shared objects"
# lets tell all the .so files this package provides in .provides-so
scanelf --nobanner --soname "$@" | while read etype soname file; do
# if soname field is missing, soname will be the filepath
# we only want shared libs
sover=0
case $soname in
*.so|*.so.[0-9]*)
soname=${soname##*/}
case "$file" in
*.so.[0-9]*) sover=${file##*.so.};;
esac
echo "$soname $sover"
;;
esac
done > "$controldir"/.provides-so
# now find the so dependencies
scanelf --nobanner --recursive --needed "$datadir" | tr ' ' ':' \
| awk -F ":" '$1 == "ET_DYN" || $1 == "ET_EXEC" {print $2}' \
| sed 's:,:\n:g' | sort -u \
| while read i; do
# only add files that are not self provided
grep -q -w "^$i" "$controldir"/.provides-so \
|| echo $i
done > "$controldir"/.needs-so
}
create_apks() { create_apks() {
local file local file= dir= name= ver= apk= datadir=
getpkgver || return 1 getpkgver || return 1
mkdir -p "$PKGDEST" mkdir -p "$PKGDEST"
if [ "$arch" != "noarch" ] && ! options_has "!tracedeps"; then
for file in "$pkgbasedir"/.control.*/.PKGINFO; do
dir="${file%/.PKGINFO}"
name="$(pkginfo_val pkgname $file)"
datadir="$pkgbasedir"/$name
subpkgname=$name
scan_shared_objects "$name" "$dir" "$datadir"
done
fi
for file in "$pkgbasedir"/.control.*/.PKGINFO; do for file in "$pkgbasedir"/.control.*/.PKGINFO; do
local dir="${file%/.PKGINFO}" dir="${file%/.PKGINFO}"
local name=$(pkginfo_val pkgname $file) name=$(pkginfo_val pkgname $file)
local ver=$(pkginfo_val pkgver $file) ver=$(pkginfo_val pkgver $file)
local apk=$name-$ver.apk apk=$name-$ver.apk
local datadir="$pkgbasedir"/$name datadir="$pkgbasedir"/$name
subpkgname=$name
trace_apk_deps "$name" "$dir" || return 1 trace_apk_deps "$name" "$dir" || return 1
msg "Creating $apk..." msg "Compressing data..."
( (
cd "$datadir" cd "$datadir"
# data.tar.gz # data.tar.gz
@ -961,6 +1002,7 @@ create_apks() {
fi fi
tar -c "$@" | abuild-tar --hash | gzip -9 >"$dir"/data.tar.gz tar -c "$@" | abuild-tar --hash | gzip -9 >"$dir"/data.tar.gz
msg "Create checksum..."
# append the hash for data.tar.gz # append the hash for data.tar.gz
local sha256=$(sha256sum "$dir"/data.tar.gz | cut -f1 -d' ') local sha256=$(sha256sum "$dir"/data.tar.gz | cut -f1 -d' ')
echo "datahash = $sha256" >> "$dir"/.PKGINFO echo "datahash = $sha256" >> "$dir"/.PKGINFO
@ -971,10 +1013,12 @@ create_apks() {
| gzip -9 > control.tar.gz | gzip -9 > control.tar.gz
abuild-sign -q control.tar.gz || exit 1 abuild-sign -q control.tar.gz || exit 1
msg "Create $apk"
# create the final apk # create the final apk
cat control.tar.gz data.tar.gz > "$PKGDEST"/$apk cat control.tar.gz data.tar.gz > "$PKGDEST"/$apk
) )
done done
subpkgname=
} }
clean_abuildrepo() { clean_abuildrepo() {