pkg_fix_deps: Look only in select locations

Also removes subshell, pipe, find, etc.

Stops the package manager from running ldd on upwards of 4000
files when building Python.

The code remains dumb in that it /uses/ ldd's error handling to
figure out which files to operate on. It now just runs on way
less files as it has a restricted search path.

If any paths are missing, do let me know. I think I have included
all places of interest (and I get same outputs with this commit
and without).
This commit is contained in:
Dylan Araps 2021-07-17 12:27:11 +03:00
parent 88bbd83020
commit 4ca35d8122
No known key found for this signature in database
GPG Key ID: 13295DAC2CF13B5C
1 changed files with 63 additions and 44 deletions

107
kiss
View File

@ -584,62 +584,81 @@ pkg_fix_deps() {
tmp_file_copy "${PWD##*/}" depends depends tmp_file_copy "${PWD##*/}" depends depends
tmp_file "${PWD##*/}" depends-fixed tmp_file "${PWD##*/}" depends-fixed
find "$pkg_dir/${PWD##*/}/" -type f 2>/dev/null | while read -r _file; do case $_file in
# Look only in these locations for files of interest (libraries,
# programs, etc). This includes all subdirectories. Old behavior
# would run ldd on all files (upwards of 4000 for Python).
*/sbin/?*|*/bin/?*|*/lib/?*|*/lib??/?*|*/lib???/?*|*/lib????/?*)
while read -r _fix_file; do # The readelf mode requires ldd's output to resolve the library
ldd_buf=$(ldd -- "$_fix_file" 2>/dev/null) || continue # path for a given file. If ldd fails, silently skip the file.
elf_buf=$("$cmd_elf" -d "$_fix_file" 2>/dev/null) || elf_buf=$ldd_buf ldd_buf=$(ldd -- "$_file" 2>/dev/null) || continue
while read -r line || [ "$line" ]; do # Attempt to get information from readelf. If this fails (or we
case $line in *NEEDED*\[*\] | *'=>'*) # are in ldd mode), do full ldd mode (which has the downside of
# readelf: 0x0000 (NEEDED) Shared library: [libjson-c.so.5] # listing dependencies of dependencies (and so on)).
line=${line##*\[} elf_buf=$("$cmd_elf" -d "$_file" 2>/dev/null) || elf_buf=$ldd_buf
line=${line%%\]*}
# Resolve library path. # Iterate over the output of readelf or ldd, extract file names,
# ldd: libjson-c.so.5 => /lib/libjson-c.so.5 ... # resolve their paths and finally, figure out their owner.
case $cmd_elf in while read -r lib; do case $lib in *NEEDED*\[*\] | *'=>'*)
*readelf) line=${ldd_buf#*" $line => "} ;; # readelf: 0x0000 (NEEDED) Shared library: [libjson-c.so.5]
*) line=${line##*=> } ;; lib=${lib##*\[}
esac lib=${lib%%\]*}
line=${line%% *}
# Skip files owned by libc and POSIX. # Resolve library path.
case ${line##*/} in # ldd: libjson-c.so.5 => /lib/libjson-c.so.5 ...
ld-* |\ case $cmd_elf in
lib[cm].so* |\ *readelf) lib=${ldd_buf#*" $lib => "} ;;
libcrypt.so* |\ *) lib=${lib##*=> } ;;
libdl.so* |\
libmvec.so* |\
libpthread.so* |\
libresolv.so* |\
librt.so* |\
libtrace.so* |\
libutil.so* |\
libxnet.so* |\
ldd)
continue
;;
*)
# Skip file if owned by current package
pkg_owner -l "/${line#/}\$" "$PWD/manifest" &&
continue
pkg_owner -l "/${line#/}\$" "$@" &&
printf '%s\n' "$pkg_owner"
;;
esac
esac esac
done <<EOF || : lib=${lib%% *}
# Skip files owned by libc and POSIX.
case ${lib##*/} in
ld-* |\
lib[cm].so* |\
libcrypt.so* |\
libdl.so* |\
libmvec.so* |\
libpthread.so* |\
libresolv.so* |\
librt.so* |\
libtrace.so* |\
libutil.so* |\
libxnet.so* |\
ldd)
continue
esac
# Skip file if owned by current package
! pkg_owner -l "/${lib#/}\$" manifest ||
continue
! pkg_owner -l "/${lib#/}\$" "$@" ||
printf '%s\n' "$pkg_owner"
esac done <<EOF || :
$elf_buf $elf_buf
EOF EOF
done | sort -uk1,1 "$_tmp_file_pre" - > "$_tmp_file" esac done < manifest |
# Sort the depends file (including the existing depends file) and
# remove any duplicate entries. This can't take into account comments
# so they remain rather than being replaced.
sort -uk1,1 "$_tmp_file_pre" - > "$_tmp_file"
# If the depends file was modified, show a diff and replace it. # If the depends file was modified, show a diff and replace it.
! [ -s "$_tmp_file" ] || { ! [ -s "$_tmp_file" ] || {
diff -U 3 "$_tmp_file_pre" "$_tmp_file" 2>/dev/null || : diff -U 3 "$_tmp_file_pre" "$_tmp_file" 2>/dev/null || :
# Replace the existing depends file if one exists, otherwise this
# just moves the file to its final resting place.
mv -f "$_tmp_file" depends mv -f "$_tmp_file" depends
# Generate a new manifest as we may be the creator of the depends
# file. This could otherwise be implemented by inserting a line
# at the correct place in the existing manifest.
pkg_manifest "${PWD##*/}" pkg_manifest "${PWD##*/}"
} }
} }