From 4ca35d8122943c07cdd7d055bccdb605e687dba5 Mon Sep 17 00:00:00 2001 From: Dylan Araps Date: Sat, 17 Jul 2021 12:27:11 +0300 Subject: [PATCH] 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). --- kiss | 107 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 63 insertions(+), 44 deletions(-) diff --git a/kiss b/kiss index c4423e7..2b4e5b4 100755 --- a/kiss +++ b/kiss @@ -584,62 +584,81 @@ pkg_fix_deps() { tmp_file_copy "${PWD##*/}" depends depends 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 - ldd_buf=$(ldd -- "$_fix_file" 2>/dev/null) || continue - elf_buf=$("$cmd_elf" -d "$_fix_file" 2>/dev/null) || elf_buf=$ldd_buf + # The readelf mode requires ldd's output to resolve the library + # path for a given file. If ldd fails, silently skip the file. + ldd_buf=$(ldd -- "$_file" 2>/dev/null) || continue - while read -r line || [ "$line" ]; do - case $line in *NEEDED*\[*\] | *'=>'*) - # readelf: 0x0000 (NEEDED) Shared library: [libjson-c.so.5] - line=${line##*\[} - line=${line%%\]*} + # Attempt to get information from readelf. If this fails (or we + # are in ldd mode), do full ldd mode (which has the downside of + # listing dependencies of dependencies (and so on)). + elf_buf=$("$cmd_elf" -d "$_file" 2>/dev/null) || elf_buf=$ldd_buf - # Resolve library path. - # ldd: libjson-c.so.5 => /lib/libjson-c.so.5 ... - case $cmd_elf in - *readelf) line=${ldd_buf#*" $line => "} ;; - *) line=${line##*=> } ;; - esac - line=${line%% *} + # Iterate over the output of readelf or ldd, extract file names, + # resolve their paths and finally, figure out their owner. + while read -r lib; do case $lib in *NEEDED*\[*\] | *'=>'*) + # readelf: 0x0000 (NEEDED) Shared library: [libjson-c.so.5] + lib=${lib##*\[} + lib=${lib%%\]*} - # Skip files owned by libc and POSIX. - case ${line##*/} 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 - ;; - - *) - # Skip file if owned by current package - pkg_owner -l "/${line#/}\$" "$PWD/manifest" && - continue - - pkg_owner -l "/${line#/}\$" "$@" && - printf '%s\n' "$pkg_owner" - ;; - esac + # Resolve library path. + # ldd: libjson-c.so.5 => /lib/libjson-c.so.5 ... + case $cmd_elf in + *readelf) lib=${ldd_buf#*" $lib => "} ;; + *) lib=${lib##*=> } ;; esac - done < "$_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. ! [ -s "$_tmp_file" ] || { 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 + + # 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##*/}" } }