From c9cfefda12815ad95c580259cc4f9463b02abaa5 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Mon, 27 Feb 2023 18:28:50 +0100 Subject: [PATCH 09/N] makepkg: port strip/debug to Windows --- scripts/libmakepkg/executable/meson.build | 1 - scripts/libmakepkg/tidy/strip.sh.in | 208 +++++++++++++--------- scripts/makepkg.sh.in | 2 +- 3 files changed, 121 insertions(+), 90 deletions(-) diff --git a/scripts/libmakepkg/executable/meson.build b/scripts/libmakepkg/executable/meson.build index f6474eb..535da57 100644 --- a/scripts/libmakepkg/executable/meson.build +++ b/scripts/libmakepkg/executable/meson.build @@ -4,7 +4,6 @@ sources = [ 'ccache.sh.in', 'checksum.sh.in', 'distcc.sh.in', - 'debugedit.sh.in', 'gpg.sh.in', 'gzip.sh.in', 'pacman.sh.in', diff --git a/scripts/libmakepkg/tidy/strip.sh.in b/scripts/libmakepkg/tidy/strip.sh.in index db35916..8918a0c 100644 --- a/scripts/libmakepkg/tidy/strip.sh.in +++ b/scripts/libmakepkg/tidy/strip.sh.in @@ -31,93 +31,55 @@ packaging_options+=('strip' 'debug') tidy_modify+=('tidy_strip') -build_id() { - LANG=C readelf -n "$1" | sed -n '/Build ID/ { s/.*: //p; q; }' -} - -source_files() { - # This function does two things: - # - # 1) rewrites source file locations for packages not respecting prefix- - # map switches. This ensures all source file references in debug - # info point to $dbgsrcdir. - # - # 2) outputs a list of files from the package source files to stdout - # while stripping the $dbgsrcdir prefix - - LANG=C debugedit --no-recompute-build-id \ - --base-dir "${srcdir}" \ - --dest-dir "${dbgsrcdir}" \ - --list-file /dev/stdout "$1" \ - | sort -zu | tr '\0' '\n' -} - -package_source_files() { - local binary=$1 - - local file dest t - while IFS= read -r t; do - file="${srcdir}/${t}" - dest="${dbgsrc}/${t}" - mkdir -p "${dest%/*}" - if [[ -f "$file" ]]; then - cp -- "$file" "$dest" - fi - done < <(source_files "$binary") -} - collect_debug_symbols() { 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 "$dbgdir/.build-id/${bid:0:2}/${bid:2}.debug" ]]; then + case "$(file -bi "$binary")" in + *application/x-dosexec* | *application/vnd.microsoft.portable-executable*) + if check_option "debug" "y"; then + if [[ -f "$dbgdir/$binary.debug" ]]; then return fi - elif [[ -f "$dbgdir/$binary.debug" ]]; then - return - fi - - # copy source files to debug directory - package_source_files "$binary" - # copy debug symbols to debug directory - mkdir -p "$dbgdir/${binary%/*}" + # copy debug symbols to debug directory + mkdir -p "$dbgdir/${binary%/*}" + msg2 "Separating debug info from $binary into $dbgdir/$binary.debug" + # create a dbg file with proper debug info: + objcopy --only-keep-debug "$binary" "$dbgdir/$binary.debug" + + msg2 "Creating a debuginfo link to $dbgdir/$binary.debug in $binary" + local tempfile=$(mktemp "$binary.XXXXXX") + objcopy --add-gnu-debuglink="$dbgdir/${binary#/}.debug" "$binary" "$tempfile" + cat "$tempfile" > "$binary" + rm "$tempfile" + + msg2 "Separating (again) debug info from $binary into $dbgdir/$binary.debug" + objcopy --only-keep-debug "$binary" "$dbgdir/$binary.debug" + + msg2 "Removing old .gnu_debuglink section from $binary" + objcopy --remove-section=.gnu_debuglink "$binary" + + # strip debug-info from the original file + objcopy --strip-debug "$binary" + msg2 "Creating (again) a debuginfo link to $dbgdir/$binary.debug in $binary" + tempfile=$(mktemp "$binary.XXXXXX") + objcopy --add-gnu-debuglink="$dbgdir/${binary#/}.debug" "$binary" "$tempfile" + cat "$tempfile" > "$binary" + rm "$tempfile" + # This way dbg file gets a .gnu_debuglink section (doesn't matter where + # it's pointing), and its contents pass the CRC32 check + + # create any needed hardlinks + while IFS= read -rd '' file ; do + if [[ "${binary}" -ef "${file}" && ! -f "$dbgdir/${file}.debug" ]]; then + mkdir -p "$dbgdir/${file%/*}" + ln "$dbgdir/${binary}.debug" "$dbgdir/${file}.debug" + fi + done < <(find . -type f -perm -u+w -print0 2>/dev/null) - # abandon processing files that are not a recognised format - if ! objcopy --only-keep-debug "$binary" "$dbgdir/$binary.debug" 2>/dev/null; then - return fi - - local tempfile=$(mktemp "$binary.XXXXXX") - objcopy --add-gnu-debuglink="$dbgdir/${binary#/}.debug" "$binary" "$tempfile" - cat "$tempfile" > "$binary" - rm "$tempfile" - - # create any needed hardlinks - while IFS= read -rd '' file ; do - if [[ "${binary}" -ef "${file}" && ! -f "$dbgdir/${file}.debug" ]]; then - mkdir -p "$dbgdir/${file%/*}" - ln "$dbgdir/${binary}.debug" "$dbgdir/${file}.debug" - fi - done < <(find . -type f -perm -u+w -print0 2>/dev/null) - - if [[ -n "$bid" ]]; then - local target - mkdir -p "$dbgdir/.build-id/${bid:0:2}" - - target="../../../../../${binary#./}" - target="${target/..\/..\/usr\/lib\/}" - target="${target/..\/usr\/}" - ln -s "$target" "$dbgdir/.build-id/${bid:0:2}/${bid:2}" - - target="../../${binary#./}.debug" - ln -s "$target" "$dbgdir/.build-id/${bid:0:2}/${bid:2}.debug" - fi - fi + ;; + esac } strip_file(){ @@ -148,21 +110,91 @@ tidy_strip() { [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S" if check_option "debug" "y"; then - dbgdir="$pkgdirbase/$pkgbase-@DEBUGSUFFIX@/usr/lib/debug" + dbgdir="$pkgdirbase/$pkgbase-@DEBUGSUFFIX@" dbgsrcdir="${DBGSRCDIR:-/usr/src/debug}/${pkgbase}" dbgsrc="$pkgdirbase/$pkgbase-@DEBUGSUFFIX@$dbgsrcdir" mkdir -p "$dbgdir" "$dbgsrc" fi local binary strip_flags - find . -type f -perm -u+w -print0 2>/dev/null | LC_ALL=C sort -z | while IFS= read -rd '' binary ; do - # skip filepaths that cause stripping issues - ideally these should be temporary - # guile-2.2 - [[ "$binary" =~ .*/guile/.*\.go$ ]] && continue - - local STATICLIB=0 - case "$(LC_ALL=C readelf -h "$binary" 2>/dev/null)" in - *Type:*'DYN (Shared object file)'*) # Libraries (.so) or Relocatable binaries + # *.so: Apache2 modules, OCaml stublibs, Ruby modules + # *.oct: Octave modules + # *.cmxs: OCaml natdynlink modules: http://gallium.inria.fr/~frisch/ndl.txt + find * -type f ! -name '*.dll.a' ! -name '*.lib' \ + -a \( -name '*.a' -o -name '*.dll' -o -name '*.exe' -o -name '*.so' -o -name '*.so.*' -o -name '*.oct' -o -name '*.cmxs' \) -print0 \ + -o -type f -executable ! -name '*.dll' ! -name '*.exe' ! -name '*.so' ! -name '*.so.[0-9]*' ! -name '*.oct' ! -name '*.cmxs' ! -name '*.a' ! -name '*.la' ! -name '*.lib' ! -name '*.exe.manifest' ! -name '*.exe.config' ! -name '*.dll.config' ! -name '*.mdb' ! -name '*-config' ! -name '*.csh' ! -name '*.sh' ! -name '*.pl' ! -name '*.pm' ! -name '*.py' ! -name '*.rb' ! -name '*.tcl' -print0 | \ + while IFS= read -d $'\0' binary + do + local STRIPLTO=0 + # Skip thin archives from stripping + case "${binary##*/}" in + *.a) + if [ "$(head -c 7 "${binary}")" = '!' ] + then + continue + fi + ;; + esac + + # assure this is actually a binary object + if [ "$(head -c 2 "${binary}")" = '#!' ] + then + # sometimes .exe will be appended where it does not belong + case "${exe}" in + usr/lib/hevea/*.exe) ;; + *.exe) mv "${binary}" "${binary%.exe}" ;; + esac + continue + fi + + # OCaml bytecode must not be stripped + # Magic number is at end of file: + # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=256900#74 + # http://cygwin.com/ml/cygwin-apps/2010-10/msg00057.html + # + # Perl Archive (PAR) binaries must not be stripped + # https://rt.cpan.org/Public/Bug/Display.html?id=18536 + # http://cygwin.com/ml/cygwin-apps/2012-07/msg00088.html + case $(tail -c 12 "${binary}" | tr '\012\0' '%') in + %PAR\.pm%) continue ;; + Caml1999X0[0-9][0-9]) continue ;; + esac + + # Mono assemblies must not be stripped, but remove .mdb debug symbols, + # and make them non-executable so they're not launched by MS .NET + if LC_ALL=C file -b "${binary}" 2>&1 | grep -q "Mono/\.Net assembly" + then + chmod 0644 "${binary}" + rm -f "${binary}.mdb" + continue + fi + + # check for .exe from non-automake Makefile which install(1) didn't fix + # strip(1) used to take care of this, but not anymore + case ${CHOST} in + *-*-cygwin*|*-*-mingw*|*-*-msys*) + case "${binary##*/}" in + *.dll|*.exe|*.sfx|*.so|*.so.[0-9]*|*.oct|*.cmxs) ;; + # make sure this isn't some oddly named DLL + *) if LANG=en_US.UTF-8 LC_ALL=C objdump -f "${binary}" | grep -Eq '^start address 0x(0000000[01])?00401[0-9a-e][0-9a-e]0' + then + mv "${binary}" "${binary}.exe" + binary+=.exe + fi ;; + esac + ;; + esac + chmod 0755 "${binary}"; + + case "$(@FILECMD@ -bi "$binary")" in + *application/x-dosexec*) # Windows executables and dlls (file <=5.43) + strip_flags="$STRIP_SHARED";; + *application/vnd.microsoft.portable-executable*) # Windows executables and dlls (file >=5.44) + strip_flags="$STRIP_SHARED";; + *application/x-archive*) # Static and Import Libraries (*.a and *.dll.a) + strip_flags="$STRIP_STATIC" + STRIPLTO=1;; + *application/x-sharedlib*) # Libraries (.so) strip_flags="$STRIP_SHARED";; *Type:*'DYN (Position-Independent Executable file)'*) # Relocatable binaries strip_flags="$STRIP_SHARED";; diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index aa2d88d..6eefa98 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -627,7 +627,7 @@ create_debug_package() { local pkgdir="$pkgdirbase/$pkgbase-@DEBUGSUFFIX@" # check if we have any debug symbols to package - if dir_is_empty "$pkgdir/usr/lib/debug"; then + if dir_is_empty "$pkgdir"; then return 0 fi