[pacman-dev] [PATCH] WIP: makepkg: rework libprovides

Allan McRae allan at archlinux.org
Thu Jun 16 04:59:21 EDT 2011


This reworks the implmentation of libprovides for the following
benefits:
 - Moves functionality from write_pkginfo() to find_libprovides()
 - Only calculates the version for libraries specifically requested
   and not all libraries. This has the disadvantage of running find
   over the $pkgdir for as many libraries as needed, but is unlikely
   to be an issue due to caching.
 - The order of the provides array in the PKGBUILD is kept in the
   package
 - There are more warning messages when things fail and those that
   were there are no longer errors (as I do not think failure of
   libprovides should result in complete packaging failure)
 - It is now modular so can be easy extended to other library types
   other than ELF *.so.

Signed-off-by: Allan McRae <allan at archlinux.org>
---

I cut and pasted the actual finding of the soarch/soversion etc, but that obviously
needs fixed.  WTF is the comment "# 64" supposed to mean?  I also would like
documentation about why we need the [ -z "$sofile" ] test (reminder: needs adjusted
to double bracket format).  Also, why do we extract "soname" when that should be
what was already given in the provides array?


 scripts/makepkg.sh.in |   83 ++++++++++++++++++++++++++-----------------------
 1 files changed, 44 insertions(+), 39 deletions(-)

diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 7527329..dae229a 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -980,30 +980,47 @@ find_libdepends() {
 }
 
 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}")
+	local libprovides missing
+	for p in ${provides[@]}; do
+		missing=0
+		case "$p" in
+			*.so)
+				filename=$(find "$pkgdir" -type f -name $p\*)
+				if [[ $filename ]]; then
+					# 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\.}"
+
+						libprovides=(${libprovides[@]} "${soname}=${soversion}-${soarch}")
+					else
+						warning "$(gettext "Library listed in %s is not a shared object: %s")" "'provides'" "$p"
+						libprovides=(${libprovides[@]} "$p")
+					fi
+				else
+					libprovides=(${libprovides[@]} "$p")
+					missing=1
 				fi
-			fi
-    fi
+				;;
+			*)
+				libprovides=(${libprovides[@]} "$p")
+				;;
+		esac
+
+		if (( missing )); then
+			warning "$(gettext "Can not find library listed in %s: %s")" "'provides'" "$p"
+		fi
 	done
+
+	echo ${libprovides[@]}
 }
 
 write_pkginfo() {
@@ -1037,13 +1054,15 @@ write_pkginfo() {
 	[[ $groups ]]     && printf "group = %s\n"     "${groups[@]}"
 	[[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]}"
 	[[ $conflicts ]]  && printf "conflict = %s\n"  "${conflicts[@]}"
+
+	provides=("$(find_libprovides)")
+	[[ $provides ]]   && printf "provides = %s\n"  "${provides[@]}"
+
 	[[ $backup ]]     && printf "backup = %s\n"    "${backup[@]}"
 
-	local it
 
-	libprovides=$(find_libprovides)
+	local it
 	libdepends=$(find_libdepends)
-	provides=("${provides[@]}" ${libprovides})
 	depends=("${depends[@]}" ${libdepends})
 
 	for it in "${depends[@]}"; do
@@ -1059,20 +1078,6 @@ write_pkginfo() {
 		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 not find library listed in %s: %s")" "'provides'" "$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.5.4



More information about the pacman-dev mailing list