FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > ArchLinux > ArchLinux Pacman Development

 
 
LinkBack Thread Tools
 
Old 12-25-2011, 05:52 AM
Allan McRae
 
Default makepkg: rework libprovides

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@archlinux.org>
---
scripts/makepkg.sh.in | 85 +++++++++++++++++++++++++++----------------------
1 files changed, 47 insertions(+), 38 deletions(-)

diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 64b33c6..08c4384 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -1076,30 +1076,51 @@ 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##*/}"
+ local libprovides missing
+ for p in ${provides[@]}; do
+ missing=0
+ case "$p" in
+ *.so)
+ local filename=$(find "$pkgdir" -type f -name $p*)
+ # packages may provide multiple versions of the same library
+ for fn in ${filename[@]}; do
+ # check if we really have a shared object
+ if LC_ALL=C readelf -h "$fn" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then
+ # get the string binaries link to (e.g. libfoo.so.1.2 -> libfoo.so.1)
+ local sofile=$(LC_ALL=C readelf -d "$fn" 2>/dev/null | sed -n 's/.*Library soname: [(.*)].*/1/p')
+ if [[ -z "$sofile" ]]; then
+ warning "$(gettext "Library listed in %s is not versioned: %s")" "'provides'" "$p"
+ libprovides=(${libprovides[@]} "$p")
+ continue
+ fi

- # 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}")
+ # get the library architecture (32 or 64 bit)
+ local soarch=$(LC_ALL=C readelf -h "$fn" | sed -n 's/.*Class.*ELF(32|64)/1/p')
+
+ # extract the library major version
+ local soversion="${sofile##*.so.}"
+
+ libprovides=(${libprovides[@]} "${p}=${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() {
@@ -1133,13 +1154,15 @@ write_pkginfo() {
[[ $groups ]] && printf "group = %s
" "${groups[@]}"
[[ $optdepends ]] && printf "optdepend = %s
" "${optdepends[@]//+([[:space:]])/ }"
[[ $conflicts ]] && printf "conflict = %s
" "${conflicts[@]}"
+
+ provides=("$(find_libprovides)")
+ [[ $provides ]] && printf "provides = %s
" "${provides[@]}"
+
[[ $backup ]] && printf "backup = %s
" "${backup[@]}"

- local it

- libprovides=$(find_libprovides)
+ local it
libdepends=$(find_libdepends)
- provides=("${provides[@]}" ${libprovides})
depends=("${depends[@]}" ${libdepends})

for it in "${depends[@]}"; do
@@ -1155,20 +1178,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 "Cannot 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.8.1
 
Old 12-25-2011, 09:06 AM
Florian Pritz
 
Default makepkg: rework libprovides

First off, this patch creates a syntax error.

On 25.12.2011 07:52, Allan McRae wrote:
> - 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.

Maybe you could create a search string like the following? This won't
preserve the order, but it will traverse the file system only once and
according to the find manpage it's POSIX compliant.

find /usr/lib -type f ( -name libx264.so* -o -name libc.so* -o -name
libarchive.so* )

> - 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)

I think it should because libraries hardly move between packages or
change their names and the packager might not see the message and push a
package with incorrect provides.

It might be a good idea not to abort right away though. You could check
all entries and abort later, but I think you shouldn't create a package
since the packager will have to fix the incorrect entry and
rebuild/repackage anyway.

> - It is now modular so can be easy extended to other library types
> other than ELF *.so.
>
> Signed-off-by: Allan McRae <allan@archlinux.org>
> ---
> scripts/makepkg.sh.in | 85 +++++++++++++++++++++++++++----------------------
> 1 files changed, 47 insertions(+), 38 deletions(-)
>
> diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
> index 64b33c6..08c4384 100644
> --- a/scripts/makepkg.sh.in
> +++ b/scripts/makepkg.sh.in
> @@ -1076,30 +1076,51 @@ 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##*/}"
> + local libprovides missing
> + for p in ${provides[@]}; do
> + missing=0
> + case "$p" in
> + *.so)
> + local filename=$(find "$pkgdir" -type f -name $p*)
> + # packages may provide multiple versions of the same library
> + for fn in ${filename[@]}; do
> + # check if we really have a shared object
> + if LC_ALL=C readelf -h "$fn" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then
> + # get the string binaries link to (e.g. libfoo.so.1.2 -> libfoo.so.1)
> + local sofile=$(LC_ALL=C readelf -d "$fn" 2>/dev/null | sed -n 's/.*Library soname: [(.*)].*/1/p')
> + if [[ -z "$sofile" ]]; then
> + warning "$(gettext "Library listed in %s is not versioned: %s")" "'provides'" "$p"
> + libprovides=(${libprovides[@]} "$p")
> + continue
> + fi
>
> - # 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}")
> + # get the library architecture (32 or 64 bit)
> + local soarch=$(LC_ALL=C readelf -h "$fn" | sed -n 's/.*Class.*ELF(32|64)/1/p')
> +
> + # extract the library major version
> + local soversion="${sofile##*.so.}"
> +
> + libprovides=(${libprovides[@]} "${p}=${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

This else block doesn't have any matching if statement. The one with
"Library listed in %s is not a shared object" already closes
'if LC_ALL=C readelf -h "$fn" 2>/dev/null | grep -q '.*Type:.*DYN
(Shared object file).*'; then'

--
Florian Pritz
 
Old 12-25-2011, 09:36 AM
Allan McRae
 
Default makepkg: rework libprovides

On 25/12/11 20:06, Florian Pritz wrote:
> First off, this patch creates a syntax error.

That is fixed on my working branch - I will resend.

> On 25.12.2011 07:52, Allan McRae wrote:
>> - 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.
>
> Maybe you could create a search string like the following? This won't
> preserve the order, but it will traverse the file system only once and
> according to the find manpage it's POSIX compliant.
>
> find /usr/lib -type f ( -name libx264.so* -o -name libc.so* -o -name
> libarchive.so* )

I do not see that being worth the effort of creating the find command.
Even for the largest of packages the find will take a fraction of a
second with the files being cached.

>> - 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)
>
> I think it should because libraries hardly move between packages or
> change their names and the packager might not see the message and push a
> package with incorrect provides.

If the package does not see a warning in the last few lines of the build
output, then they need to stop packaging...

> It might be a good idea not to abort right away though. You could check
> all entries and abort later, but I think you shouldn't create a package
> since the packager will have to fix the incorrect entry and
> rebuild/repackage anyway.

There are two cases where this occurs:
1) the library has no soname information
2) the listed provide is not a shared object

If we make these errors and someone wants to add a provide that hits one
of these conditions, then there is nothing they can do. This could be
especially possible with #1...

Allan
 
Old 12-25-2011, 09:38 AM
Allan McRae
 
Default makepkg: rework libprovides

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@archlinux.org>
---

Fixed version.

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

diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 64b33c6..8c6984d 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -1076,30 +1076,53 @@ 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)
+ local filename=$(find "$pkgdir" -type f -name $p*)
+ if [[ $filename ]]; then
+ # packages may provide multiple versions of the same library
+ for fn in ${filename[@]}; do
+ # check if we really have a shared object
+ if LC_ALL=C readelf -h "$fn" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then
+ # get the string binaries link to (e.g. libfoo.so.1.2 -> libfoo.so.1)
+ local sofile=$(LC_ALL=C readelf -d "$fn" 2>/dev/null | sed -n 's/.*Library soname: [(.*)].*/1/p')
+ if [[ -z "$sofile" ]]; then
+ warning "$(gettext "Library listed in %s is not versioned: %s")" "'provides'" "$p"
+ libprovides=(${libprovides[@]} "$p")
+ continue
+ fi
+
+ # get the library architecture (32 or 64 bit)
+ local soarch=$(LC_ALL=C readelf -h "$fn" | sed -n 's/.*Class.*ELF(32|64)/1/p')
+
+ # extract the library major version
+ local soversion="${sofile##*.so.}"
+
+ libprovides=(${libprovides[@]} "${p}=${soversion}-${soarch}")
+ else
+ warning "$(gettext "Library listed in %s is not a shared object: %s")" "'provides'" "$p"
+ libprovides=(${libprovides[@]} "$p")
+ fi
+ done
+ 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() {
@@ -1133,13 +1156,15 @@ write_pkginfo() {
[[ $groups ]] && printf "group = %s
" "${groups[@]}"
[[ $optdepends ]] && printf "optdepend = %s
" "${optdepends[@]//+([[:space:]])/ }"
[[ $conflicts ]] && printf "conflict = %s
" "${conflicts[@]}"
+
+ provides=($(find_libprovides))
+ [[ $provides ]] && printf "provides = %s
" "${provides[@]}"
+
[[ $backup ]] && printf "backup = %s
" "${backup[@]}"

- local it

- libprovides=$(find_libprovides)
+ local it
libdepends=$(find_libdepends)
- provides=("${provides[@]}" ${libprovides})
depends=("${depends[@]}" ${libdepends})

for it in "${depends[@]}"; do
@@ -1155,20 +1180,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 "Cannot 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.8.1
 
Old 12-25-2011, 04:02 PM
Florian Pritz
 
Default makepkg: rework libprovides

On 25.12.2011 11:38, Allan McRae wrote:
> 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@archlinux.org>

Signed-off-by: Florian Pritz <bluewind@xinu.at>

> ---
>
> Fixed version.
>
> scripts/makepkg.sh.in | 89 +++++++++++++++++++++++++++---------------------
> 1 files changed, 50 insertions(+), 39 deletions(-)
>
> diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
> index 64b33c6..8c6984d 100644


--
Florian Pritz
 

Thread Tools




All times are GMT. The time now is 10:37 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org