From: Florian Pritz <bluewind@xssn.at> The user adds libaries to the provides array without a version. These must end with .so. Example: provides=(readline libreadline.so) find_soprovides() looks for .so files (not symlinks because these could point outside of pkgdir) in $pkgdir, extracts the library soname (ld links the binary to this name) and outputs provides seperated by spaces. This list contains all libraries provided by the package. Example: libfoo.so=3_64 write_pkginfo() only keeps .so provides with version information and warns the user about unneded ones. Support-by: Thomas Bächler <thomas@archlinux.org> Support-by: Christoph Schied <Christoph.Schied@uni-ulm.de> Signed-off-by: Florian Pritz <bluewind@server-speed.net> --- scripts/makepkg.sh.in | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 46 insertions(+), 1 deletions(-) diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index 6ebfac0..06631f4 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -917,6 +917,34 @@ tidy_install() { fi } +find_soprovides() { + local soprovides + local os=$(uname -s | tr [:upper:] [:lower:]) + find "$pkgdir" -type f -name \*.so\* | while read filename + do + # check if we really have a shared object + if LC_ALL=C readelf -h "$filename" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then + # 64 + soarch=$(LC_ALL=C readelf -h "$filename" | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p') + # get the string binaries link to: libfoo.so.1.2 -> libfoo.so.1 + sofile=$(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p') + [ -z "$sofile" ] && sofile="${$filename##*/}" + + # extract the library name: libfoo.so + soname="${sofile%%\.so\.*}.so" + # extract the major version: 1 + soversion="${sofile##*\.so\.}" + if in_array "${soname}" ${provides[@]}; then + if ! in_array "${soname}=${soversion}-${soarch}" ${soprovides[@]}; then + # libfoo.so=1-elf_x86_64_linux + echo "${soname}=${soversion}-${soarch}" + soprovides=(${soprovides[@]} "${soname}=${soversion}-${soarch}") + fi + fi + fi + done +} + write_pkginfo() { local builddate=$(date -u "+%s") if [[ -n $PACKAGER ]]; then @@ -950,10 +978,27 @@ write_pkginfo() { [[ $depends ]] && printf "depend = %s\n" "${depends[@]}" [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]}" [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}" - [[ $provides ]] && printf "provides = %s\n" "${provides[@]}" [[ $backup ]] && printf "backup = %s\n" "${backup[@]}" local it + + soprovides=$(find_soprovides) + provides=("${provides[@]}" ${soprovides}) + + for it in "${provides[@]}"; do + # ignore versionless entires (those come from the PKGBUILD) + if [[ $it = *.so ]]; then + # check if the entry has been found by find_soprovides + # if not, it's unneeded; tell the user so he can remove it + if [[ ! $soprovides =~ (^|\s)${it}=.* ]]; then + error "$(gettext "Can't find library listed in \$provides: %s")" "$it" + return 1 + fi + else + echo "provides = $it" + fi + done + for it in "${packaging_options[@]}"; do local ret="$(check_option $it)" if [[ $ret != "?" ]]; then -- 1.7.3.5