[pacman-dev] [PATCH 0/7] Split debugging symbols into separate package
This patchset allows makepkg to automatically create packages from the stripped debugging symbols. Patches 1, 4 and 6 are only mildly related... but a fixes that were "needed" along the way. The idea is to add options=('debug') to your PKGBUILD or in makepkg.conf and then makepkg will add DEBUG_CFLAGS and DEBUG_CXXFLAGS (defined in makepkg.conf) to their buildflag counterparts. When both "debug" and "strip" are specified in the options, the debug symbols are copied into a separate folder before the files are stripped. The main debugging symbols are in /usr/lib/debug/path/to/file (e.g. /usr/lib/debug/usr/bin/pacman) and are hardlinked if required. If the binary was linked with a build ID, the relevant symlinks in /usr/lib/debug/.build_id are created. Testing is needed... Allan McRae (7): makepkg: always run tidy_install on repackaging makepkg: add option to include debugging compiler flags makepkg: move debug symbol stripping to separate function makepkg: always use pkg/$pkgname as $pkgdir makepkg: strip debugging symbols into separate folder makepkg: output the name of the package being created makepkg: create package from stripped debug symbols doc/PKGBUILD.5.txt | 5 ++ doc/makepkg.conf.5.txt | 13 +++++ etc/makepkg.conf.in | 8 ++- scripts/makepkg.sh.in | 137 ++++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 136 insertions(+), 27 deletions(-) -- 1.7.12.1
When using "makepkg -R" without a packge function, we should still
run tidy_install as the user might have added other packaging options
such as (e.g.) '!emptydir' to remove enpty directories on repackaging.
Of course we can not revert some options when repackaging without a
package function.
Signed-off-by: Allan McRae
On Mon, Sep 24, 2012 at 12:44:29AM +1000, Allan McRae wrote:
When using "makepkg -R" without a packge function, we should still run tidy_install as the user might have added other packaging options such as (e.g.) '!emptydir' to remove enpty directories on repackaging. Of course we can not revert some options when repackaging without a package function.
Ack, assuming you fix the typos in the commit message.
Signed-off-by: Allan McRae
--- scripts/makepkg.sh.in | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index d387b7d..40e8c2f 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -2669,7 +2669,6 @@ if (( INFAKEROOT )); then if (( BUILDFUNC )); then run_build (( CHECKFUNC )) && run_check - tidy_install fi else warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()" @@ -2677,8 +2676,8 @@ if (( INFAKEROOT )); then fi else run_package - tidy_install fi + tidy_install create_package else run_split_packaging @@ -2808,15 +2807,11 @@ else if (( ! SPLITPKG )); then if (( PKGFUNC )); then run_package - tidy_install - else - if (( ! REPKG )); then - tidy_install - else + elif (( REPKG )); then warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
Isn't it time we made this an error?
plain "$(gettext "File permissions may not be preserved.")" - fi fi + tidy_install create_package else run_split_packaging -- 1.7.12.1
On 24/09/12 01:49, Dave Reisner wrote:
+ elif (( REPKG )); then
warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
Isn't it time we made this an error?
I just looked up when we introduced the package() function and it was more than three years ago... I suggest we just remove support of PKGBUILDs without a package() function. This would make it easy to unify the single and split packaging. Do we just do that straight away for pacman-4.1, or add a deprecation notice whenever there is a build() function but no package()? Allan
Add a "debug" option that appends the compiler flags specified in the
variables DEBUG_CFLAGS and DEBUG_CXXFLAGS in makepkg.conf to their
counterpart buildflags.
Signed-off-by: Allan McRae
Move stripping of files to a spearate function that will be expanded
for the handling of creating debug symbol packages.
Signed-off-by: Allan McRae
On Mon, Sep 24, 2012 at 12:44:31AM +1000, Allan McRae wrote:
Move stripping of files to a spearate function that will be expanded for the handling of creating debug symbol packages.
Signed-off-by: Allan McRae
--- scripts/makepkg.sh.in | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index 7b516ff..5283d73 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -1421,6 +1421,11 @@ run_package() { run_function_safe "$pkgfunc" }
+strip_file() { + local binary=$1; shift + strip $@ $binary
"$binary"
+} + tidy_install() { cd_safe "$pkgdir" msg "$(gettext "Tidying install...")" @@ -1475,16 +1480,19 @@ tidy_install() { # make sure library stripping variables are defined to prevent excess stripping [[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S" [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S" - local binary + local binary strip_flags find . -type f -perm -u+w -print0 2>/dev/null | while read -d '' binary ; do case "$(file -bi "$binary")" in *application/x-sharedlib*) # Libraries (.so) - strip $STRIP_SHARED "$binary";; + strip_flags=($STRIP_SHARED);;
This is a little strange since $STRIP_SHARED and friends are simple variables. Why not just leave it as a simple string assignment?
*application/x-archive*) # Libraries (.a) - strip $STRIP_STATIC "$binary";; + strip_flags=($STRIP_STATIC);; *application/x-executable*) # Binaries - strip $STRIP_BINARIES "$binary";; + strip_flags=($STRIP_BINARIES);; + *) + continue ;; esac + strip_file $binary ${strip_flags[@]}
"$binary"
done fi
-- 1.7.12.1
Unify split and single packages to always use a folder within pkg/
as thier $pkgdir. This will allow a folder for storing a package with
stripped debug symbols to be added within pkg/ too.
Signed-off-by: Allan McRae
On Mon, Sep 24, 2012 at 12:44:32AM +1000, Allan McRae wrote:
Unify split and single packages to always use a folder within pkg/ as thier $pkgdir. This will allow a folder for storing a package with stripped debug symbols to be added within pkg/ too.
Signed-off-by: Allan McRae
--- scripts/makepkg.sh.in | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index 5283d73..c857060 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -2678,6 +2678,9 @@ if (( INFAKEROOT )); then fi
if (( ! SPLITPKG )); then + pkgdir="$pkgdir/$pkgname" + mkdir -p "$pkgdir" + chmod a-s "$pkgdir"
Can't we just use mkdir's -m flag here? It's specified by POSIX.
if (( ! PKGFUNC )); then if (( ! REPKG )); then if (( BUILDFUNC )); then @@ -2693,6 +2696,7 @@ if (( INFAKEROOT )); then fi tidy_install create_package + pkgdir="${pkgdir%/*}" else run_split_packaging fi @@ -2819,6 +2823,9 @@ else (( CHECKFUNC )) && run_check fi if (( ! SPLITPKG )); then + pkgdir="$pkgdir/$pkgname" + mkdir -p "$pkgdir" + chmod a-s "$pkgdir"
And here...
if (( PKGFUNC )); then run_package elif (( REPKG )); then @@ -2827,6 +2834,7 @@ else fi tidy_install create_package + pkgdir="${pkgdir%/*}" else run_split_packaging fi -- 1.7.12.1
On 24/09/12 01:55, Dave Reisner wrote:
+ pkgdir="$pkgdir/$pkgname"
+ mkdir -p "$pkgdir" + chmod a-s "$pkgdir" Can't we just use mkdir's -m flag here? It's specified by POSIX.
Note this is used in multiple other places in makepkg. I seem to recall we did not use the "-m" flag for some reason, but I can not remember why. Maybe Dan can shed some light here? Anyway, I have just realized we only need it on the creation of $srcdir and $startdir/pkg. All directories created within them have no need for it... Allan
When using the "debug" option in combination with "strip", move the
debugging symbols into a separate directory ($pkgdir-debug/usr/lib/debug)
suitable for creating a package from.
Create hardlinks between debugging symbols of hardlinked files and add
symlinks in the .build_id directory if the binary has a build ID.
Signed-off-by: Allan McRae
On 24/09/12 00:44, Allan McRae wrote:
When using the "debug" option in combination with "strip", move the debugging symbols into a separate directory ($pkgdir-debug/usr/lib/debug) suitable for creating a package from.
Create hardlinks between debugging symbols of hardlinked files and add symlinks in the .build_id directory if the binary has a build ID.
Signed-off-by: Allan McRae
--- scripts/makepkg.sh.in | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index c857060..df1823d 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -1421,8 +1421,55 @@ run_package() { run_function_safe "$pkgfunc" }
+build_id() { + local id + id=$(LANG=C readelf -n $1 | sed -n '/Build ID/ { s/.*: //p; q; }') + printf "%s\n" "$id" +} + strip_file() { local binary=$1; shift + + if check_option "debug" "y"; then + local bid=$(build_id $binary) + + # has this file already been stripped + if [[ -n "$bid" ]]; then + if [[ -f $pkgdir-debug/usr/lib/debug/.build_id/${bid:0:2}/${bid:2}.debug ]]; then + return + fi + elif [[ -f $pkgdir-debug/usr/lib/debug/$binary.debug ]]; then + return + fi + + mkdir -p $pkgdir-debug/usr/lib/debug/${binary%/*} + objcopy --only-keep-debug $binary $pkgdir-debug/usr/lib/debug/$binary.debug + + # create any needed hardlinks + while read -d '' file ; do + if [[ "${binary}" -ef "${file}" && + ! -f $pkgdir-debug/usr/lib/debug/${file}.debug ]]; then + mkdir -p $pkgdir-debug/usr/lib/debug/${file%/*} + ln $pkgdir-debug/usr/lib/debug/${binary}.debug \ + $pkgdir-debug/usr/lib/debug/${file}.debug + return
delete...
+ fi + done < <(find . -type f -perm -u+w -print0 2>/dev/null) + + if [[ -n "$bid" ]]; then + local target + mkdir -p $pkgdir-debug/usr/lib/debug/.build_id/${bid:0:2} + + target="../../../../../${binary#./}" + target=${target/..\/..\/usr\/lib\/} + target=${target/..\/usr\/} + ln -s $target $pkgdir-debug/usr/lib/debug/.build_id/${bid:0:2}/${bid:2} + + target="../../${binary#./}.debug" + ln -s $target $pkgdir-debug/usr/lib/debug/.build_id/${bid:0:2}/${bid:2}.debug + fi + fi + strip $@ $binary }
@@ -1480,6 +1527,11 @@ tidy_install() { # make sure library stripping variables are defined to prevent excess stripping [[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S" [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S" + + if check_option "debug" "y"; then + mkdir -p $pkgdir-debug/usr/lib/debug + fi + local binary strip_flags find . -type f -perm -u+w -print0 2>/dev/null | while read -d '' binary ; do case "$(file -bi "$binary")" in
On Mon, Sep 24, 2012 at 12:44:33AM +1000, Allan McRae wrote:
When using the "debug" option in combination with "strip", move the debugging symbols into a separate directory ($pkgdir-debug/usr/lib/debug) suitable for creating a package from.
Create hardlinks between debugging symbols of hardlinked files and add symlinks in the .build_id directory if the binary has a build ID.
Signed-off-by: Allan McRae
--- scripts/makepkg.sh.in | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index c857060..df1823d 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -1421,8 +1421,55 @@ run_package() { run_function_safe "$pkgfunc" }
+build_id() { + local id + id=$(LANG=C readelf -n $1 | sed -n '/Build ID/ { s/.*: //p; q; }') + printf "%s\n" "$id" +}
This whole function should just be the readelf|sed: build_id() { LANG=C readelf -n $1 | sed -n '/Build ID/ { s/.*: //p; q; }' }
+ strip_file() { local binary=$1; shift + + if check_option "debug" "y"; then + local bid=$(build_id $binary) + + # has this file already been stripped + if [[ -n "$bid" ]]; then + if [[ -f $pkgdir-debug/usr/lib/debug/.build_id/${bid:0:2}/${bid:2}.debug ]]; then + return + fi + elif [[ -f $pkgdir-debug/usr/lib/debug/$binary.debug ]]; then + return + fi + + mkdir -p $pkgdir-debug/usr/lib/debug/${binary%/*} + objcopy --only-keep-debug $binary $pkgdir-debug/usr/lib/debug/$binary.debug
quoting
+ + # create any needed hardlinks + while read -d '' file ; do + if [[ "${binary}" -ef "${file}" && + ! -f $pkgdir-debug/usr/lib/debug/${file}.debug ]]; then + mkdir -p $pkgdir-debug/usr/lib/debug/${file%/*} + ln $pkgdir-debug/usr/lib/debug/${binary}.debug \ + $pkgdir-debug/usr/lib/debug/${file}.debug
quoting
+ return + fi + done < <(find . -type f -perm -u+w -print0 2>/dev/null) + + if [[ -n "$bid" ]]; then + local target + mkdir -p $pkgdir-debug/usr/lib/debug/.build_id/${bid:0:2}
quoting
+ + target="../../../../../${binary#./}" + target=${target/..\/..\/usr\/lib\/} + target=${target/..\/usr\/}
Ew.
+ ln -s $target $pkgdir-debug/usr/lib/debug/.build_id/${bid:0:2}/${bid:2}
quoting
+ + target="../../${binary#./}.debug" + ln -s $target $pkgdir-debug/usr/lib/debug/.build_id/${bid:0:2}/${bid:2}.debug
quoting
+ fi + fi + strip $@ $binary }
@@ -1480,6 +1527,11 @@ tidy_install() { # make sure library stripping variables are defined to prevent excess stripping [[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S" [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S" + + if check_option "debug" "y"; then + mkdir -p $pkgdir-debug/usr/lib/debug
"$pkgdir-debug/usr/lib/debug"
+ fi + local binary strip_flags find . -type f -perm -u+w -print0 2>/dev/null | while read -d '' binary ; do case "$(file -bi "$binary")" in -- 1.7.12.1
On 24/09/12 02:05, Dave Reisner wrote:
+ target="../../../../../${binary#./}"
+ target=${target/..\/..\/usr\/lib\/} + target=${target/..\/usr\/} Ew.
Yes... but any suggestions on how to improve it? That was the best I could come up with.
Although it should be currently quite obvious what package is being
created when "Creating package..." is printed, it will not be in the
future when a debug package is potentially created too. Also, given
$pkgname is always correctly set when split packaging now, we no
longer need to pass that around.
Signed-off-by: Allan McRae
Signed-off-by: Allan McRae
On 24/09/12 00:44, Allan McRae wrote:
This patchset allows makepkg to automatically create packages from the stripped debugging symbols.
Patches 1, 4 and 6 are only mildly related... but a fixes that were "needed" along the way.
The idea is to add options=('debug') to your PKGBUILD or in makepkg.conf and then makepkg will add DEBUG_CFLAGS and DEBUG_CXXFLAGS (defined in makepkg.conf) to their buildflag counterparts.
When both "debug" and "strip" are specified in the options, the debug symbols are copied into a separate folder before the files are stripped. The main debugging symbols are in /usr/lib/debug/path/to/file (e.g. /usr/lib/debug/usr/bin/pacman) and are hardlinked if required. If the binary was linked with a build ID, the relevant symlinks in /usr/lib/debug/.build_id are created.
Testing is needed...
valgrind without debug package installed: ==27108== Invalid free() / delete / delete[] / realloc() ==27108== at 0x4029F8C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==27108== by 0x8048760: ??? (in /usr/bin/foo) ==27108== by 0x41AD604: (below main) (in /usr/lib/libc-2.16.so) ==27108== Address 0x4342028 is 0 bytes inside a block of size 4 free'd ==27108== at 0x4029F8C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==27108== by 0x8048754: ??? (in /usr/bin/foo) ==27108== by 0x41AD604: (below main) (in /usr/lib/libc-2.16.so) valgrind with debug package: ==27142== Invalid free() / delete / delete[] / realloc() ==27142== at 0x4029F8C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==27142== by 0x8048760: main (test.cpp:8) ==27142== Address 0x4342028 is 0 bytes inside a block of size 4 free'd ==27142== at 0x4029F8C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==27142== by 0x8048754: main (test.cpp:7) Similar things happen with gdb! Allan
participants (2)
-
Allan McRae
-
Dave Reisner