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