]> git.donarmstrong.com Git - debhelper.git/blob - dh_strip
r1673: * Bump dh_strip's recommended bintuils dep to current. Closes: #237304
[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 named 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 will
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 Note that if you use this option, your package should build-depend on
62 binutils (>= 2.14.90.0.7).
63
64 =item B<-k>, B<--keep-debug>
65
66 Debug symbols will be retained, but split into an independant
67 file in usr/lib/debug/ in the package build directory. --dbg-package
68 is easier to use than this option, but this option is more flexible.
69
70 Note that if you use this option, your package should build-depend on
71 binutils (>= 2.12.90.0.9).
72
73 =back
74
75 =head1 NOTES
76
77 If the DEB_BUILD_OPTIONS environment variable contains "nostrip", nothing
78 will be stripped, in accordance with Debian policy.
79
80 =head1 CONFORMS TO
81
82 Debian policy, version 3.0.1
83
84 =cut
85
86 init();
87
88 # This variable can be used to turn off stripping (see Policy).
89 if (defined $ENV{DEB_BUILD_OPTIONS} && $ENV{DEB_BUILD_OPTIONS} =~ /nostrip/) {
90         exit;
91 }
92
93 # I could just use `file $_[0]`, but this is safer
94 sub get_file_type {
95         my $file=shift;
96         open (FILE, '-|') # handle all filenames safely
97                 || exec('file', $file)
98                 || die "can't exec file: $!";
99         my $type=<FILE>;
100         close FILE;
101         return $type;
102 }
103
104 # Check if a file is an elf binary, shared library, or static library,
105 # for use by File::Find. It'll fill the following 3 arrays with anything
106 # it finds:
107 my (@shared_libs, @executables, @static_libs);
108 sub testfile {
109         return if -l $_ or -d $_; # Skip directories and symlinks always.
110
111         # See if we were asked to exclude this file.
112         # Note that we have to test on the full filename, including directory.
113         my $fn="$File::Find::dir/$_";
114         foreach my $f (@{$dh{EXCLUDE}}) {
115                 return if ($fn=~m/\Q$f\E/);
116         }
117
118         # Is it a debug library in a debug subdir?
119         return if $fn=~m/debug\/.*\.so/;
120
121         # Does its filename look like a shared library?
122         if (m/.*\.so.*?/) {
123                 # Ok, do the expensive test.
124                 my $type=get_file_type($_);
125                 if ($type=~m/.*ELF.*shared.*/) {
126                         push @shared_libs, $fn;
127                         return;
128                 }
129         }
130         
131         # Is it executable? -x isn't good enough, so we need to use stat.
132         my (undef,undef,$mode,undef)=stat(_);
133         if ($mode & 0111) {
134                 # Ok, expensive test.
135                 my $type=get_file_type($_);
136                 if ($type=~m/.*ELF.*(executable|shared).*/) {
137                         push @executables, $fn;
138                         return;
139                 }
140         }
141         
142         # Is it a static library, and not a debug library?
143         if (m/lib.*\.a$/ && ! m/.*_g\.a$/) {
144                 push @static_libs, $fn;
145                 return;
146         }
147 }
148
149 sub make_debug {
150         my $file=shift;
151         my $tmp=shift;
152         my $desttmp=shift;
153
154         my ($base_file)=$file=~/^\Q$tmp\E(.*)/;
155         my $debug_path=$desttmp."/usr/lib/debug/".$base_file;
156         my $debug_dir=dirname($debug_path);
157         if (! -d $debug_dir) {
158                 doit("install", "-d", $debug_dir);
159         }
160         doit("objcopy", "--only-keep-debug", $file, $debug_path);
161         # No reason for this to be executable.
162         doit("chmod", 644, $debug_path);
163         return $debug_path;
164 }
165
166 sub attach_debug {
167         my $file=shift;
168         my $debug_path=shift;
169         doit("objcopy", "--add-gnu-debuglink", $debug_path, $file);
170 }
171
172 foreach my $package (@{$dh{DOPACKAGES}}) {
173         my $tmp=tmpdir($package);
174
175         # Support for keeping the debugging symbols in a detached file.
176         my $keep_debug=$dh{KEEP_DEBUG};
177         my $debugtmp=$tmp;
178         if (ref $dh{DEBUGPACKAGES} && grep { $_ eq $package } @{$dh{DEBUGPACKAGES}}) {
179                 $keep_debug=1;
180                 $debugtmp=tmpdir($package."-dbg");
181         }
182         
183         @shared_libs=@executables=@static_libs=();
184         find(\&testfile,$tmp);
185
186         foreach (@shared_libs) {
187                 my $debug_path = make_debug($_, $tmp, $debugtmp) if $keep_debug;
188                 # Note that all calls to strip on shared libs
189                 # *must* inclde the --strip-unneeded.
190                 doit("strip","--remove-section=.comment",
191                         "--remove-section=.note","--strip-unneeded",$_);
192                 attach_debug($_, $debug_path) if $keep_debug;
193         }
194         
195         foreach (@executables) {
196                 my $debug_path = make_debug($_, $tmp, $debugtmp) if $keep_debug;
197                 doit("strip","--remove-section=.comment",
198                         "--remove-section=.note",$_);
199                 attach_debug($_, $debug_path) if $keep_debug
200         }
201
202         foreach (@static_libs) {
203                 doit("strip","--strip-debug",$_);
204         }
205 }
206
207 =head1 SEE ALSO
208
209 L<debhelper(7)>
210
211 This program is a part of debhelper.
212
213 =head1 AUTHOR
214
215 Joey Hess <joeyh@debian.org>
216
217 =cut