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