]> git.donarmstrong.com Git - debhelper.git/blob - dh_strip
r1614: * Patch from Andrew Suffield <asuffield@debian.org> to make dh_strip
[debhelper.git] / dh_strip
1 #!/usr/bin/perl -w
2
3 =head1 NAME
4
5 dh_strip - strip executables, shared libraries, and some static libraries
6
7 =cut
8
9 use strict;
10 use File::Find;
11 use Debian::Debhelper::Dh_Lib;
12
13 =head1 SYNOPSIS
14
15 B<dh_strip> [S<I<debhelper options>>] [B<-X>I<item>] [--dbg-package=package] [--keep-debug]
16
17 =head1 DESCRIPTION
18
19 dh_strip is a debhelper program that is responsible for stripping
20 executables, shared libraries, and static libraries that are not used for
21 debugging.
22
23 This program examines your package build directories and works out what
24 to strip on its own. It uses L<file(1)> and file permisions and filenames
25 to figure out what files are shared libraries (*.so), executable binaries,
26 and static (lib*.a) and debugging libraries (lib*_g.a, debug/*.so), and
27 strips each as much as is possible. (Which is not at all for debugging
28 libraries.) In general it seems to make very good guesses, and will do the
29 right thing in almost all cases.
30
31 Since it is very hard to automatically guess if a file is a
32 module, and hard to determine how to strip a module, dh_strip does not
33 currently deal with stripping binary modules such as .o files.
34
35 =head1 OPTIONS
36
37 =over 4
38
39 =item B<-X>I<item>, B<--exclude=>I<item>
40
41 Exclude files that contain "item" anywhere in their filename from being
42 stripped. You may use this option multiple times to build up a list of
43 things to exclude.
44
45 =item B<--dbg-package=>I<package>
46
47 This option tells dh_strip that the given package has an associated "-dbg"
48 package. dh_strip will, when stripping off the debug symbols of files in
49 the given package, save them to independent files in the package build
50 directory for the "-dbg" package.
51
52 For example, you might have a package libfoo libfoo, and want to include a
53 libfoo-dbg package that contains debugging symbols. The command "dh_strip
54 --dbg-package=libfoo" will make dh_strip save the debugging symbols for
55 usr/lib/libfoo.so.0 into usr/lib/debug/usr/lib/libfoo.so.0 in the package
56 build directory for libfoo-dbg. If libfoo-dbg is installed, gdb wil
57 automatically load up the debugging symbols from it when debugging libfoo.
58
59 This option may be repeated to list more than one package.
60
61 =item B<-k>, B<--keep-debug>
62
63 Debug symbols will be retained, but split into an independant
64 file in usr/lib/debug/ in the package build directory. --dbg-package
65 is easier to use than this option, but this option is more flexible.
66
67 =back
68
69 =head1 NOTES
70
71 If the DEB_BUILD_OPTIONS environment variable contains "nostrip", nothing
72 will be stripped, in accordance with Debian policy.
73
74 =head1 CONFORMS TO
75
76 Debian policy, version 3.0.1
77
78 =cut
79
80 init();
81
82 # This variable can be used to turn off stripping (see Policy).
83 if (defined $ENV{DEB_BUILD_OPTIONS} && $ENV{DEB_BUILD_OPTIONS} =~ /nostrip/) {
84         exit;
85 }
86
87 # I could just use `file $_[0]`, but this is safer
88 sub get_file_type {
89         my $file=shift;
90         open (FILE, '-|') # handle all filenames safely
91                 || exec('file', $file)
92                 || die "can't exec file: $!";
93         my $type=<FILE>;
94         close FILE;
95         return $type;
96 }
97
98 # Check if a file is an elf binary, shared library, or static library,
99 # for use by File::Find. It'll fill the following 3 arrays with anything
100 # it finds:
101 my (@shared_libs, @executables, @static_libs);
102 sub testfile {
103         return if -l $_ or -d $_; # Skip directories and symlinks always.
104
105         # See if we were asked to exclude this file.
106         # Note that we have to test on the full filename, including directory.
107         my $fn="$File::Find::dir/$_";
108         foreach my $f (@{$dh{EXCLUDE}}) {
109                 return if ($fn=~m/\Q$f\E/);
110         }
111
112         # Is it a debug library in a debug subdir?
113         return if $fn=~m/debug\/.*\.so/;
114
115         # Does its filename look like a shared library?
116         if (m/.*\.so.*?/) {
117                 # Ok, do the expensive test.
118                 my $type=get_file_type($_);
119                 if ($type=~m/.*ELF.*shared.*/) {
120                         push @shared_libs, $fn;
121                         return;
122                 }
123         }
124         
125         # Is it executable? -x isn't good enough, so we need to use stat.
126         my (undef,undef,$mode,undef)=stat(_);
127         if ($mode & 0111) {
128                 # Ok, expensive test.
129                 my $type=get_file_type($_);
130                 if ($type=~m/.*ELF.*(executable|shared).*/) {
131                         push @executables, $fn;
132                         return;
133                 }
134         }
135         
136         # Is it a static library, and not a debug library?
137         if (m/lib.*\.a$/ && ! m/.*_g\.a$/) {
138                 push @static_libs, $fn;
139                 return;
140         }
141 }
142
143 sub make_debug {
144         my $file=shift;
145         my $tmp=shift;
146         my $desttmp=shift;
147
148         my ($base_file)=$file=~/^$tmp(.*)/;
149         my $debug_path=$desttmp."/usr/lib/debug/".$base_file;
150         my $debug_dir=dirname($debug_path);
151         if (! -d $debug_dir) {
152                 doit("install", "-d", $debug_dir);
153         }
154         doit("objcopy", "--only-keep-debug", $file, $debug_path);
155         # No reason for this to be executable.
156         doit("chmod", 644, $debug_path);
157         return $debug_path;
158 }
159
160 sub attach_debug {
161         my $file=shift;
162         my $debug_path=shift;
163         doit("objcopy", "--add-gnu-debuglink", $debug_path, $file);
164 }
165
166 foreach my $package (@{$dh{DOPACKAGES}}) {
167         my $tmp=tmpdir($package);
168
169         # Support for keeping the debugging symbols in a detached file.
170         my $keep_debug=$dh{KEEP_DEBUG};
171         my $debugtmp=$tmp;
172         if (ref $dh{DEBUGPACKAGES} && grep { $_ eq $package } @{$dh{DEBUGPACKAGES}}) {
173                 $keep_debug=1;
174                 $debugtmp=tmpdir($package."-dbg");
175         }
176         
177         @shared_libs=@executables=@static_libs=();
178         find(\&testfile,$tmp);
179
180         foreach (@shared_libs) {
181                 my $debug_path = make_debug($_, $tmp, $debugtmp) if $keep_debug;
182                 # Note that all calls to strip on shared libs
183                 # *must* inclde the --strip-unneeded.
184                 doit("strip","--remove-section=.comment",
185                         "--remove-section=.note","--strip-unneeded",$_);
186                 attach_debug($_, $debug_path) if $keep_debug;
187         }
188         
189         foreach (@executables) {
190                 my $debug_path = make_debug($_, $tmp, $debugtmp) if $keep_debug;
191                 doit("strip","--remove-section=.comment",
192                         "--remove-section=.note",$_);
193                 attach_debug($_, $debug_path) if $keep_debug
194         }
195
196         foreach (@static_libs) {
197                 doit("strip","--strip-debug",$_);
198         }
199 }
200
201 =head1 SEE ALSO
202
203 L<debhelper(7)>
204
205 This program is a part of debhelper.
206
207 =head1 AUTHOR
208
209 Joey Hess <joeyh@debian.org>
210
211 =cut