summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2011-06-14 08:30:23 -0500
committerDan McGee <dan@archlinux.org>2011-06-14 08:30:23 -0500
commitc206b3a6d503e57691664b94e68ba85760bd0b6c (patch)
treeec90f860d62a5903fb5b0229d61d0bbb34a98ed4
parentd3553768652cb99ccc944285bfdf618768223dfa (diff)
parent5689478c68bdda8ecbe0eae9a5bd28b072632b26 (diff)
Merge remote-tracking branch 'florian/sodeps'
-rw-r--r--doc/PKGBUILD.5.txt9
-rw-r--r--scripts/makepkg.sh.in87
2 files changed, 94 insertions, 2 deletions
diff --git a/doc/PKGBUILD.5.txt b/doc/PKGBUILD.5.txt
index b47f429d..015db5fe 100644
--- a/doc/PKGBUILD.5.txt
+++ b/doc/PKGBUILD.5.txt
@@ -149,6 +149,11 @@ name. The syntax is: `source=('filename::url')`.
form 'name<>version', where <> is one of five comparisons: >= (greater
than or equal to), <= (less than or equal to), = (equal to), > (greater
than), or < (less than).
++
+If the dependency name appears to be a library (ends with .so), makepkg will
+try to find a binary that depends on the library in the built package and
+append the version needed by the binary. Appending the version yourself
+disables auto detection.
*makedepends (array)*::
An array of packages this package depends on to build but are not
@@ -185,6 +190,10 @@ name. The syntax is: `source=('filename::url')`.
dependency of other packages. Provisions involving the '>' and '<'
operators are invalid as only specific versions of a package may be
provided.
++
+If the provision name appears to be a library (ends with .so), makepkg will
+try to find the library in the built package and append the correct
+version. Appending the version yourself disables auto detection.
*replaces (array)*::
An array of packages this package should replace. This can be used
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index b3081fcd..419036dc 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -932,6 +932,58 @@ tidy_install() {
fi
}
+find_libdepends() {
+ local libdepends
+ find "$pkgdir" -type f -perm -u+x | 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
+ # 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
+ # extract the library name: libfoo.so
+ soname="${sofile%%\.so\.*}.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
+ echo "${soname}=${soversion}-${soarch}"
+ libdepends=(${libdepends[@]} "${soname}=${soversion}-${soarch}")
+ fi
+ fi
+ done
+ done
+}
+
+find_libprovides() {
+ local libprovides
+ 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}" ${libprovides[@]}; then
+ # libfoo.so=1-64
+ echo "${soname}=${soversion}-${soarch}"
+ libprovides=(${libprovides[@]} "${soname}=${soversion}-${soarch}")
+ fi
+ fi
+ fi
+ done
+}
+
write_pkginfo() {
local builddate=$(date -u "+%s")
if [[ -n $PACKAGER ]]; then
@@ -961,13 +1013,44 @@ write_pkginfo() {
[[ $license ]] && printf "license = %s\n" "${license[@]}"
[[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}"
[[ $groups ]] && printf "group = %s\n" "${groups[@]}"
- [[ $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
+
+ libprovides=$(find_libprovides)
+ libdepends=$(find_libdepends)
+ provides=("${provides[@]}" ${libprovides})
+ depends=("${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
+ if [[ ! $libdepends =~ (^|\s)${it}=.* ]]; then
+ error "$(gettext "Can't find library listed in \$depends: %s")" "$it"
+ return 1
+ fi
+ else
+ echo "depend = $it"
+ fi
+ done
+
+ 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_libprovides
+ # if not, it's unneeded; tell the user so he can remove it
+ if [[ ! $libprovides =~ (^|\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