Skip to content
Snippets Groups Projects
dh_setup_copyright 3.38 KiB
Newer Older
dh_setup_copyright - extract source file names from DWARF debug information in ELF binaries via dwarf2sources

=cut

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

our $VERSION = DH_BUILTIN_VERSION;

=head1 SYNOPSIS

B<dh_setup_copyright> [S<I<debhelper options>>] [B<-X>I<item>] [S<B<--> I<params>>]
B<dh_setup_copyright> is a debhelper program that generates the list for source
file names used to build every binary. This list is extracted from DWARF debug
information by running L<dwarf2sources(1)> on every ELF binaries in the package
and saving the output to /usr/share/doc/<package>.

=head1 OPTIONS

=over 4

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

Exclude files that contain I<item> anywhere in their filename from being
extracted. You may use this option multiple times to build up a list of
things to exclude.

=back

=head1 NOTES

If the B<DEB_BUILD_OPTIONS> environment variable contains B<nodwarf2sources>,
this procedure is skipped.

=cut

init();

# This variable can be used to turn off file name extraction.
exit 0 if get_buildoption('nodwarf2sources');

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 _;
	if (is_so_or_exec_elf_file($fn)) {
		push(@elf_files, $fn);
	}
	return;
}

sub extract_filenames {
	my ($fname_list, $tmpfolder, @binaries) = @_;
	# In order to have the list of file names as will be find in the rootfs
	# generate the file name relative to tmpdir($package), execute the command
	# in chdir and save the output to $tmp_fname_list file
	doit_noerror({chdir => $tmpfolder}, "rm", "-f", $fname_list);
	print "Extracting source file names to $fname_list from @binaries in tmp folder $tmpfolder\n";
	doit_noerror({chdir => $tmpfolder}, "dwarf2sources", "-o", $fname_list, @binaries);
}

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

	print "Processing package $package for source file name extraction\n";
	my $fname_dir = "usr/share/doc/" . $package;
	if (-l "$tmp/$fname_dir") {
		my $target = readlink "$tmp/$fname_dir";
		my $package_doc = basename($target);
		$fname_dir = "usr/share/doc/$package_doc";
	}
	my $arch = package_binary_arch($package);
	my $fname_list = "$fname_dir/" . $package . "_bin2sources_" . $arch . ".json";
	print "Checking file $fname_list\n";
	if (-e "$tmp/$fname_list") {
		print "File $tmp/$fname_list already exists, skipping\n";
		next;
	}

	@elf_files = ();
	find({
			wanted => \&testfile,
			no_chdir => 1,
		 }, $tmp);

	if (not @elf_files) {
		print "Package $package has no binaries to check, skipping\n";
		next;
	}

	# Consistent order;
	@elf_files = sort(@elf_files);
	my ($unique_files, $hardlinks) = find_hardlinks(@elf_files);

	foreach (@elf_files) {
		my $file = substr($_, length($tmp) + 1);
		push(@binaries, $file);
	}

	print "Checking $fname_dir\n";
	if (not -e "$tmp/$fname_dir") {
		print "Folder $tmp/$fname_dir does not exists, creating it\n";
		mkpath("$tmp/$fname_dir");
	}

	extract_filenames($fname_list, $tmp, @binaries);
}

=head1 SEE ALSO

L<debhelper(7)>

This program is a part of debhelper.

=head1 AUTHOR

Walter Lozano <walter.lozano@collabora.com>

=cut