]> git.donarmstrong.com Git - debhelper.git/blobdiff - dh_strip
r1687: * dh_installmodules: Look for .ko files too. Closes: #248624
[debhelper.git] / dh_strip
index 2ecdcd2c957330ae47365477130bae11cd9f4b09..65c4f9f82a062195085c920ffe19dab65d9a9c41 100755 (executable)
--- a/dh_strip
+++ b/dh_strip
-#!/bin/sh -e
-#
-# Strip files.
+#!/usr/bin/perl -w
 
-PATH=debian:$PATH:/usr/lib/debhelper
-source dh_lib
+=head1 NAME
 
-for PACKAGE in $DH_DOPACKAGES; do
-       TMP=`tmpdir $PACKAGE`
+dh_strip - strip executables, shared libraries, and some static libraries
+
+=cut
+
+use strict;
+use File::Find;
+use Debian::Debhelper::Dh_Lib;
+
+=head1 SYNOPSIS
+
+B<dh_strip> [S<I<debhelper options>>] [B<-X>I<item>] [--dbg-package=package] [--keep-debug]
+
+=head1 DESCRIPTION
+
+dh_strip is a debhelper program that is responsible for stripping
+executables, shared libraries, and static libraries that are not used for
+debugging.
+
+This program examines your package build directories and works out what
+to strip on its own. It uses L<file(1)> and file permisions and filenames
+to figure out what files are shared libraries (*.so), executable binaries,
+and static (lib*.a) and debugging libraries (lib*_g.a, debug/*.so), and
+strips each as much as is possible. (Which is not at all for debugging
+libraries.) In general it seems to make very good guesses, and will do the
+right thing in almost all cases.
+
+Since it is very hard to automatically guess if a file is a
+module, and hard to determine how to strip a module, dh_strip does not
+currently deal with stripping binary modules such as .o files.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-X>I<item>, B<--exclude=>I<item>
+
+Exclude files that contain "item" anywhere in their filename from being
+stripped. You may use this option multiple times to build up a list of
+things to exclude.
+
+=item B<--dbg-package=>I<package>
+
+This option tells dh_strip that the given package has an associated "-dbg"
+package. dh_strip will, when stripping off the debug symbols of files in
+the given package, save them to independent files in the package build
+directory for the "-dbg" package.
+
+For example, you might have a package named libfoo, and want to include a
+libfoo-dbg package that contains debugging symbols. The command "dh_strip
+--dbg-package=libfoo" will make dh_strip save the debugging symbols for
+usr/lib/libfoo.so.0 into usr/lib/debug/usr/lib/libfoo.so.0 in the package
+build directory for libfoo-dbg. If libfoo-dbg is installed, gdb will
+automatically load up the debugging symbols from it when debugging libfoo.
+
+This option may be repeated to list more than one package.
+
+Note that if you use this option, your package should build-depend on
+binutils (>= 2.14.90.0.7).
+
+=item B<-k>, B<--keep-debug>
+
+Debug symbols will be retained, but split into an independant
+file in usr/lib/debug/ in the package build directory. --dbg-package
+is easier to use than this option, but this option is more flexible.
+
+Note that if you use this option, your package should build-depend on
+binutils (>= 2.12.90.0.9).
+
+=back
+
+=head1 NOTES
+
+If the DEB_BUILD_OPTIONS environment variable contains "nostrip", nothing
+will be stripped, in accordance with Debian policy.
+
+=head1 CONFORMS TO
+
+Debian policy, version 3.0.1
+
+=cut
+
+init();
+
+# This variable can be used to turn off stripping (see Policy).
+if (defined $ENV{DEB_BUILD_OPTIONS} && $ENV{DEB_BUILD_OPTIONS} =~ /nostrip/) {
+       exit;
+}
+
+# I could just use `file $_[0]`, but this is safer
+sub get_file_type {
+       my $file=shift;
+       open (FILE, '-|') # handle all filenames safely
+               || exec('file', $file)
+               || die "can't exec file: $!";
+       my $type=<FILE>;
+       close FILE;
+       return $type;
+}
+
+# Check if a file is an elf binary, shared library, or static library,
+# for use by File::Find. It'll fill the following 3 arrays with anything
+# it finds:
+my (@shared_libs, @executables, @static_libs);
+sub testfile {
+       return if -l $_ or -d $_; # Skip directories and symlinks always.
+       
+       # See if we were asked to exclude this file.
+       # Note that we have to test on the full filename, including directory.
+       my $fn="$File::Find::dir/$_";
+       foreach my $f (@{$dh{EXCLUDE}}) {
+               return if ($fn=~m/\Q$f\E/);
+       }
+
+       # Is it a debug library in a debug subdir?
+       return if $fn=~m/debug\/.*\.so/;
+
+       # Does its filename look like a shared library?
+       if (m/.*\.so.*?/) {
+               # Ok, do the expensive test.
+               my $type=get_file_type($_);
+               if ($type=~m/.*ELF.*shared.*/) {
+                       push @shared_libs, $fn;
+                       return;
+               }
+       }
+       
+       # Is it executable? -x isn't good enough, so we need to use stat.
+       my (undef,undef,$mode,undef)=stat(_);
+       if ($mode & 0111) {
+               # Ok, expensive test.
+               my $type=get_file_type($_);
+               if ($type=~m/.*ELF.*(executable|shared).*/) {
+                       push @executables, $fn;
+                       return;
+               }
+       }
+       
+       # Is it a static library, and not a debug library?
+       if (m/lib.*\.a$/ && ! m/.*_g\.a$/) {
+               # Is it a binary file, or something else (maybe a liner
+               # script on Hurd, for example? I don't use file, because
+               # file returns a varity of things on static libraries.
+               if (-B $_) {
+                       push @static_libs, $fn;
+                       return;
+               }
+       }
+}
+
+sub make_debug {
+       my $file=shift;
+       my $tmp=shift;
+       my $desttmp=shift;
+
+       my ($base_file)=$file=~/^\Q$tmp\E(.*)/;
+       my $debug_path=$desttmp."/usr/lib/debug/".$base_file;
+       my $debug_dir=dirname($debug_path);
+       if (! -d $debug_dir) {
+               doit("install", "-d", $debug_dir);
+       }
+       doit("objcopy", "--only-keep-debug", $file, $debug_path);
+       # No reason for this to be executable.
+       doit("chmod", 644, $debug_path);
+       return $debug_path;
+}
+
+sub attach_debug {
+       my $file=shift;
+       my $debug_path=shift;
+       doit("objcopy", "--add-gnu-debuglink", $debug_path, $file);
+}
+
+foreach my $package (@{$dh{DOPACKAGES}}) {
+       my $tmp=tmpdir($package);
+
+       # Support for keeping the debugging symbols in a detached file.
+       my $keep_debug=$dh{KEEP_DEBUG};
+       my $debugtmp=$tmp;
+       if (ref $dh{DEBUGPACKAGES} && grep { $_ eq $package } @{$dh{DEBUGPACKAGES}}) {
+               $keep_debug=1;
+               $debugtmp=tmpdir($package."-dbg");
+       }
        
-       # Handle executables and shared libraries.
-       for file in `find debian/$TMP -type f \( -perm +111 -or -name "*.so*" \) 2>/dev/null` ; do
-               case "`file $file`" in
-                       *ELF*shared*)
-                               doit "strip --strip-unneeded $file"
-                       ;;
-                       *ELF*executable*)
-                               doit "strip --remove-section=comment --remove-section=note $file"
-                       ;;
-               esac
-       done
-
-       # Handle static libraries.
-       for file in `find debian/$TMP -type f -name "lib*.a" 2>/dev/null` ; do
-               # Don't strip debug libraries.
-               if ! expr "$file" : ".*_g\.a" >/dev/null ; then
-                       doit "strip --strip-debug $file"
-               fi
-       done
-done
+       @shared_libs=@executables=@static_libs=();
+       find(\&testfile,$tmp);
+
+       foreach (@shared_libs) {
+               my $debug_path = make_debug($_, $tmp, $debugtmp) if $keep_debug;
+               # Note that all calls to strip on shared libs
+               # *must* inclde the --strip-unneeded.
+               doit("strip","--remove-section=.comment",
+                       "--remove-section=.note","--strip-unneeded",$_);
+               attach_debug($_, $debug_path) if $keep_debug;
+       }
+       
+       foreach (@executables) {
+               my $debug_path = make_debug($_, $tmp, $debugtmp) if $keep_debug;
+               doit("strip","--remove-section=.comment",
+                       "--remove-section=.note",$_);
+               attach_debug($_, $debug_path) if $keep_debug
+       }
+
+       foreach (@static_libs) {
+               doit("strip","--strip-debug",$_);
+       }
+}
+
+=head1 SEE ALSO
+
+L<debhelper(7)>
+
+This program is a part of debhelper.
+
+=head1 AUTHOR
+
+Joey Hess <joeyh@debian.org>
+
+=cut