diff options
author | Allan McRae <allan@archlinux.org> | 2012-05-19 23:09:22 +1000 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2012-05-20 19:04:38 -0500 |
commit | 9a76a458b898ea462666491cb74cd95372462da4 (patch) | |
tree | 58b3167faa599b36806344d6bceed7fcfc08c79b | |
parent | 81bc390dc1a66841a332948fd906c2257720f37a (diff) | |
download | pacman-9a76a458b898ea462666491cb74cd95372462da4.tar.xz |
makepkg: rework libdepends
Rewrite the handling of libdepends. The primary advantage are:
- Moves functionality from write_pkginfo() to find_libdepends().
- The order of the depends array in the PKGBUILD is kept in the package.
- An unneeded libdepends is only a warning and not an error. This allows
putting a libdepend on a library that is dlopened.
- It is now modular so can be extended to library types other than
ELF *.so.
- Finding the list of libraries a package depends only occurs when a
libdepend is specified in the depends array.
Signed-off-by: Allan McRae <allan@archlinux.org>
-rw-r--r-- | scripts/makepkg.sh.in | 100 |
1 files changed, 61 insertions, 39 deletions
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index 8d018c06..718b4e9d 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -1131,12 +1131,29 @@ tidy_install() { } find_libdepends() { - local libdepends - find "$pkgdir" -type f -perm -u+x | while read filename - do + local d sodepends; + + sodepends=0; + for d in "${depends[@]}"; do + if [[ $d = *.so ]]; then + sodepends=1; + break; + fi + done + + if (( sodepends == 0 )); then + printf '%s\n' "${depends[@]}" + return; + fi + + local libdeps filename soarch sofile soname soversion; + declare -A libdeps; + + while read filename; do # get architecture of the file; if soarch is empty it's not an ELF binary soarch=$(LC_ALL=C readelf -h "$filename" 2>/dev/null | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p') - [ -n "$soarch" ] || continue + [[ -n "$soarch" ]] || continue + # process all libraries needed by the binary for sofile in $(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -nr 's/.*Shared library: \[(.*)\].*/\1/p') do @@ -1144,19 +1161,42 @@ find_libdepends() { soname="${sofile%.so?(+(.+([0-9])))}".so # extract the major version: 1 soversion="${sofile##*\.so\.}" - if in_array "${soname}" ${depends[@]}; then - if ! in_array "${soname}=${soversion}-${soarch}" ${libdepends[@]}; then - # libfoo.so=1-64 - printf "%s" "${soname}=${soversion}-${soarch}" - libdepends+=("${soname}=${soversion}-${soarch}") + + if [[ ${libdeps[$soname]} ]]; then + if [[ ${libdeps[$soname]} != *${soversion}-${soarch}* ]]; then + libdeps[$soname]+=" ${soversion}-${soarch}" fi + else + libdeps[$soname]="${soversion}-${soarch}" fi done + done < <(find "$pkgdir" -type f -perm -u+x) + + local libdepends v + for d in "${depends[@]}"; do + case "$d" in + *.so) + if [[ ${libdeps[$d]} ]]; then + for v in ${libdeps[$d]}; do + libdepends+=("$d=$v") + done + else + warning "$(gettext "Library listed in %s is not required by any files: %s")" "'depends'" "$d" + libdepends+=("$d") + fi + ;; + *) + libdepends+=("$d") + ;; + esac done + + printf '%s\n' "${libdepends[@]}" } + find_libprovides() { - local libprovides missing + local p libprovides missing for p in "${provides[@]}"; do missing=0 case "$p" in @@ -1246,38 +1286,20 @@ write_pkginfo() { printf "size = %s\n" "$size" printf "arch = %s\n" "$pkgarch" - [[ $license ]] && printf "license = %s\n" "${license[@]}" - [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}" - [[ $groups ]] && printf "group = %s\n" "${groups[@]}" - [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]//+([[:space:]])/ }" - [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}" - mapfile -t provides < <(find_libprovides) - [[ $provides ]] && printf "provides = %s\n" "${provides[@]}" - - [[ $backup ]] && printf "backup = %s\n" "${backup[@]}" - + mapfile -t depends < <(find_libdepends) + + [[ $license ]] && printf "license = %s\n" "${license[@]}" + [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}" + [[ $groups ]] && printf "group = %s\n" "${groups[@]}" + [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}" + [[ $provides ]] && printf "provides = %s\n" "${provides[@]}" + [[ $backup ]] && printf "backup = %s\n" "${backup[@]}" + [[ $depends ]] && printf "depend = %s\n" "${depends[@]}" + [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]//+([[:space:]])/ }" + [[ $makedepends ]] && printf "makedepend = %s\n" "${makedepends[@]}" local it - mapfile -t libdepends < <(find_libdepends) - depends+=("${libdepends[@]}") - - for it in "${depends[@]}"; do - if [[ $it = *.so ]]; then - # check if the entry has been found by find_libdepends - # if not, it's unneeded; tell the user so he can remove it - printf -v re '(^|\s)%s=.*' "$it" - if [[ ! $libdepends =~ $re ]]; then - error "$(gettext "Cannot find library listed in %s: %s")" "'depends'" "$it" - return 1 - fi - else - printf "depend = %s\n" "$it" - fi - done - - [[ $makedepends ]] && printf "makedepend = %s\n" "${makedepends[@]}" - for it in "${packaging_options[@]}"; do check_option "$it" "y" case $? in |