summaryrefslogtreecommitdiff
path: root/dh_dwz
blob: 9a8e8fd11fdcf3c1ec5125a86861359ec5b98eef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/perl

=head1 NAME

dh_dwz - optimize DWARF debug information in ELF binaries via dwz

=cut

use strict;
use warnings;
use File::Find;
use Debian::Debhelper::Dh_Lib;

our $VERSION = DH_BUILTIN_VERSION;

=head1 SYNOPSIS

B<dh_dwz> [S<I<debhelper options>>] [B<-X>I<item>] [S<B<--> I<params>>]

=head1 DESCRIPTION

B<Caveat>: This tool is experimental and may disappear or change
behaviour without any notice.

B<dh_dwz> is a debhelper program that will optimize the (uncompressed)
size of the DWARF debug information in ELF binaries.  It does so by
running L<dwz(1)> on all the ELF binaries in the package.

=head1 OPTIONS

=over 4

=item B<--dwz-multifile>, B<--no-dwz-multifile>

Whether L<dwz(1)> should generate a I<multifile> from the ELF binaries
in the same package (it does by default).  When enabled, if a package
ships at least 2 ELF binaries, B<dh_dwz> will instruct L<dwz(1)> to
generate a multifile for the package.

Note this options may not work if a package contains more ELF binaries
than can fit on a single command line.  If this becomes a problem,
please pass B<--no-dwz-multifile> to work around the issue.

The generated multifile will be compressed with B<objcopy
--compress-debug-sections>.

=item B<-X>I<item>, B<--exclude=>I<item>

Exclude files that contain I<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<--> I<params>

Pass I<params> to L<dwz(1)> when it processes ELF binaries.  This is
mostly useful for setting memory related parameters (e.g. -l and -L).

=back

=head1 NOTES

If the B<DEB_BUILD_OPTIONS> environment variable contains B<nostrip>,
nothing will be stripped, in accordance with Debian policy (section
10.1 "Binaries").

While this tool technically does not remove debug information from
binaries, it is still skipped when the B<DEB_BUILD_OPTIONS>
environment variable contains B<nostrip>.  This is because B<nostrip>
is often used to optimize build times (e.g. for "build and
test"-cycles) rather than optimizing for size.

=cut

my $create_multifile = 1;

init(options => {
	'dwz-multifile!' => \$create_multifile,
});

# This variable can be used to turn off stripping (see Policy).
exit 0 if get_buildoption('nostrip');

my @elf_files;

sub testfile {
	my $fn = $_;
	return if -l $fn; # Always skip symlinks.

	# See if we were asked to exclude this file.
	# Note that we have to test on the full filename, including directory.
	if (excludefile($fn)) {
		$File::Find::prune = 1 if -d _;
		return;
	}
	return if -d _;
	# Do not process output files from dwz
	return if index($fn, '/debug/.dwz/') > -1;
	if (is_so_or_exec_elf_file($fn)) {
		push(@elf_files, $fn);
	}
	return;
}

for my $package (@{$dh{DOPACKAGES}}) {
	my $tmp = tmpdir($package);

	next if not -d $tmp;

	@elf_files = ();
	find({
			wanted => \&testfile,
			no_chdir => 1,
		 }, $tmp);
	next if not @elf_files;
	# Consistent order;
	@elf_files = sort(@elf_files);
	my ($unique_files, $hardlinks) = find_hardlinks(@elf_files);
	my @dwz_options;
	if ($create_multifile and @{$unique_files} > 1) {
		my $objcopy = cross_command($package, 'objcopy');
		my $ma_dir = dpkg_architecture_value('DEB_HOST_MULTIARCH');
		my $dwz_dir = "usr/lib/debug/.dwz/${ma_dir}";
		my $m = "${dwz_dir}/${package}.debug";
		my @dwz_options = ("-m${tmp}/${m}", "-M/${m}");
		install_dir("${tmp}/${dwz_dir}");
		doit('dwz', '-q', @dwz_options, @{$dh{U_PARAMS}}, '--', @{$unique_files});
		doit($objcopy, '--compress-debug-sections', "${tmp}/${m}");
	} else {
		xargs($unique_files, 'dwz', '-q', @{$dh{U_PARAMS}}, '--');
	}


	# Now change over any files we can that used to be hard links so
	# they are again.
	for my $hardlink (keys %{$hardlinks}) {
		my $target = $hardlinks->{$hardlink};
		# Remove old file.
		rm_files($hardlink);
		# Make new hardlink.
		doit('ln', '-f', $target, $hardlink);
	}
}

=head1 SEE ALSO

L<debhelper(7)>

This program is a part of debhelper.

=head1 AUTHOR

Niels Thykier <niels@thykier.net>

=cut