commit eccaf194e077a5177b9a82e4b930a27d059b018b Author: Adrian Perez de Castro Date: Thu Jan 19 19:05:42 2017 +0200 Use "readelf -d" instead of "ldd" for extracting dependencies diff --git a/Makefile b/Makefile index 6c70718..00bcefc 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,7 @@ install: all < lsinitcpio > $(DESTDIR)/usr/bin/lsinitcpio chmod 755 $(DESTDIR)/usr/bin/lsinitcpio $(DESTDIR)/usr/bin/mkinitcpio + install -m755 mkinitcpio-readelf-ldd $(DESTDIR)/usr/bin/mkinitcpio-readelf-ldd install -m644 mkinitcpio.conf $(DESTDIR)/etc/mkinitcpio.conf install -m755 -t $(DESTDIR)/usr/lib/initcpio init shutdown diff --git a/functions b/functions index 756b968..12d2659 100644 --- a/functions +++ b/functions @@ -584,23 +584,18 @@ add_binary() { add_file "$binary" "$dest" "$mode" # negate this so that the RETURN trap is not fired on non-binaries - ! lddout=$(ldd "$binary" 2>/dev/null) && return 0 + ! lddout=$(mkinitcpio-readelf-ldd "$binary" 2>/dev/null) && return 0 - # resolve sodeps - regex='(/.+) \(0x[a-fA-F0-9]+\)' - while read line; do - if [[ $line =~ $regex ]]; then - sodep=${BASH_REMATCH[1]} - elif [[ $line = *'not found' ]]; then - error "binary dependency \`%s' not found for \`%s'" "${line%% *}" "$1" - (( ++_builderrors )) - continue - fi - - if [[ -f $sodep && ! -e $BUILDROOT$sodep ]]; then - add_file "$sodep" "$sodep" "$(stat -Lc %a "$sodep")" - fi - done <<< "$lddout" + while read -r found sodep ; do + if [[ ${found} = '?' ]] ; then + error "binary dependency \`%s' not found for \`%s'" "${sodep}" "$1" + (( ++_builderrors )) + continue + fi + if [[ -f $sodep && ! -e $BUILDROOT$sodep ]]; then + add_file "$sodep" "$sodep" "$(stat -Lc %a "$sodep")" + fi + done <<< "$lddout" return 0 } diff --git a/mkinitcpio-readelf-ldd b/mkinitcpio-readelf-ldd new file mode 100755 index 0000000..ae56ddd --- /dev/null +++ b/mkinitcpio-readelf-ldd @@ -0,0 +1,38 @@ +#! /bin/bash +set -e + +declare -r awk_program=' +$2 == "(RUNPATH)" { print "path " substr($NF, 2, length($NF) - 2) } +$2 == "(NEEDED)" { print "name " substr($NF, 2, length($NF) - 2) } +' + +find_lib () { + local name=$1 + shift + for path in "$@" ; do + if [[ -r ${path}/${name} ]] ; then + local file="$(readlink -f "${path}")/${name}" + echo "+ ${file}" + find_deps "${file}" + return + fi + done + echo "? ${path}/$1" +} + +# Figure out whether the binary defines additional library paths. +find_deps () { + local -a lib_paths=( /usr/lib /lib ) + local -a lib_names=( ) + while read -r kind value ; do + case ${kind} in + path) lib_paths+=( "${value}" ) ;; + name) lib_names+=( "${value}" ) ;; + esac + done < <( readelf -d "$1" | awk "${awk_program}") + for name in "${lib_names[@]}" ; do + find_lib "${name}" "${lib_paths[@]}" + done +} + +find_deps "$1" | sort | uniq