From: Morten Linderud <[email protected]>

`dwz` allows us to compress the DWARF files when building debug
packages. Potentially shaving off some of the sizes of the symbols we
distribute.

https://sourceware.org/dwz/

A sample of packages built with dwz;

pacman:
  Original debug info size: 1520kB
  Size after compression:   1252kB

systemd:
  Original debug info size: 46692kB
  Size after compression:   41036kB

Signed-off-by: Morten Linderud <[email protected]>
---
 doc/makepkg.conf.5.asciidoc                   |  3 ++
 scripts/libmakepkg/executable/dwz.sh.in       | 38 +++++++++++++++++++
 .../executable/sepdebugcrcfix.sh.in           | 38 +++++++++++++++++++
 scripts/libmakepkg/tidy/strip.sh.in           | 33 ++++++++++++++--
 4 files changed, 109 insertions(+), 3 deletions(-)
 create mode 100644 scripts/libmakepkg/executable/dwz.sh.in
 create mode 100644 scripts/libmakepkg/executable/sepdebugcrcfix.sh.in

diff --git a/doc/makepkg.conf.5.asciidoc b/doc/makepkg.conf.5.asciidoc
index a0d9a6d4..2e40f27f 100644
--- a/doc/makepkg.conf.5.asciidoc
+++ b/doc/makepkg.conf.5.asciidoc
@@ -194,6 +194,9 @@ Options
                DEBUG_CXXFLAGS to their counterpart buildflags. Creates a 
separate
                package containing the debug symbols when used with `strip'.
 
+       *dwz*;;
+               Compress dwarf files inside the debug package.
+
        *lto*;;
                Enable building packages using link time optimization. Adds the
                flags specified in LTOFLAGS to CFLAGS, CXXFLAGS and LDFLAGS (or
diff --git a/scripts/libmakepkg/executable/dwz.sh.in 
b/scripts/libmakepkg/executable/dwz.sh.in
new file mode 100644
index 00000000..a540697c
--- /dev/null
+++ b/scripts/libmakepkg/executable/dwz.sh.in
@@ -0,0 +1,38 @@
+#!/usr/bin/bash
+#
+#   dwz.sh - Confirm presence of dwz binary
+#
+#   Copyright (c) 2011-2022 Pacman Development Team 
<[email protected]>
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+[[ -n "$LIBMAKEPKG_EXECUTABLE_DWZ_SH" ]] && return
+LIBMAKEPKG_EXECUTABLE_DWZ_SH=1
+
+LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
+
+source "$LIBRARY/util/message.sh"
+source "$LIBRARY/util/option.sh"
+
+executable_functions+=('executable_dwz')
+
+executable_dwz() {
+       if check_option "dwz" "y"; then
+               if ! type -p dwz>/dev/null; then
+                       error "$(gettext "Cannot find the %s binary required to 
compress dwarf files.")" "dwz"
+                       return 1
+               fi
+       fi
+}
diff --git a/scripts/libmakepkg/executable/sepdebugcrcfix.sh.in 
b/scripts/libmakepkg/executable/sepdebugcrcfix.sh.in
new file mode 100644
index 00000000..6259ac32
--- /dev/null
+++ b/scripts/libmakepkg/executable/sepdebugcrcfix.sh.in
@@ -0,0 +1,38 @@
+#!/usr/bin/bash
+#
+#   sepdebugcrcfix.sh - Confirm presence of sepdebugcrcfix binary
+#
+#   Copyright (c) 2011-2022 Pacman Development Team 
<[email protected]>
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+[[ -n "$LIBMAKEPKG_EXECUTABLE_SEPDEBUGCRCFIX_SH" ]] && return
+LIBMAKEPKG_EXECUTABLE_SEPDEBUGCRCFIX_SH=1
+
+LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
+
+source "$LIBRARY/util/message.sh"
+source "$LIBRARY/util/option.sh"
+
+executable_functions+=('executable_sepdebugcrcfix')
+
+executable_sepdebugcrcfix() {
+       if check_option "dwz" "y"; then
+               if ! type -p sepdebugcrcfix>/dev/null; then
+                       error "$(gettext "Cannot find the %s binary required to 
fix CRC.")" "sepdebugcrcfix"
+                       return 1
+               fi
+       fi
+}
diff --git a/scripts/libmakepkg/tidy/strip.sh.in 
b/scripts/libmakepkg/tidy/strip.sh.in
index 688bcf1b..8504227d 100644
--- a/scripts/libmakepkg/tidy/strip.sh.in
+++ b/scripts/libmakepkg/tidy/strip.sh.in
@@ -27,7 +27,7 @@ source "$LIBRARY/util/message.sh"
 source "$LIBRARY/util/option.sh"
 
 
-packaging_options+=('strip' 'debug')
+packaging_options+=('strip' 'debug' 'dwz')
 tidy_modify+=('tidy_strip')
 
 
@@ -52,6 +52,26 @@ source_files() {
                | sort -zu | tr '\0' '\n'
 }
 
+compress_dwarf_files(){
+       binary_files="$@"
+       readarray dwz_files < <(find "$dbgdir" -type f -name \*.debug | 
LC_ALL=C sort)
+       size_before=$(du -sk "$dbgdir" | cut -f1)
+
+       # The dwz options are taken from rpm/debugedit
+       LANG=C dwz --hardlink \
+               --quiet \
+               --relative \
+               --low-mem-die-limit 10000000 \
+               --max-die-limit 50000000 \
+               ${dwz_files[@]}
+
+       size_after=$(du -sk "$dbgdir" | cut -f1)
+       msg2 "$(gettext "Original debug info size: ${size_before}kB, size after 
compression: ${size_after}kB")"
+
+       # Some debuggers might use the CRC to find relevant debug files instead 
of the build-id
+       LANG=C sepdebugcrcfix "$dbgdir" $binary_files &>/dev/null
+}
+
 strip_file() {
        local binary=$1; shift
 
@@ -142,7 +162,8 @@ tidy_strip() {
                fi
 
                local binary strip_flags
-               find . -type f -perm -u+w -print0 2>/dev/null | while IFS= read 
-rd '' binary ; do
+               declare -a binary_files
+               while IFS= read -rd '' binary ; do
                        local STRIPLTO=0
                        case "$(LC_ALL=C readelf -h "$binary" 2>/dev/null)" in
                                *Type:*'DYN (Shared object file)'*) # Libraries 
(.so) or Relocatable binaries
@@ -166,6 +187,12 @@ tidy_strip() {
                        esac
                        strip_file "$binary" ${strip_flags}
                        (( STRIPLTO )) && strip_lto "$binary"
-               done
+                       binary_files+=("$binary")
+               done < <(find . -type f -perm -u+w -print0 2>/dev/null)
+
+               if check_option "debug" "y" && check_option "dwz" "y"; then
+                       msg2 "$(gettext "Compressign dwarf files...")"
+                       compress_dwarf_files ${binary_files[@]}
+               fi
        fi
 }
-- 
2.36.1

Reply via email to