#!/usr/bin/perl -w

=head1 NAME

dh_strip - strip executables, shared libraries, and some static libraries

=cut

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

=head1 SYNOPSIS

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

=head1 DESCRIPTION

dh_strip is a debhelper program that is responsible for stripping
executables, shared libraries, and static libraries that are not used for
debugging.

It assumes that files that have names like lib*_g.a are static libraries
used in debugging, and will not strip them.

=head1 OPTIONS

=over 4

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

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

=back

=head1 NOTES

If the DEB_BUILD_OPTIONS environment variable contains "nostrip", nothing
will be stripped, in accordance with Debian policy.

=head1 CONFORMS TO

Debian policy, version 3.0.1

=cut

init();

# This variable can be used to turn off stripping (see Policy).
if (defined $ENV{DEB_BUILD_OPTIONS} && $ENV{DEB_BUILD_OPTIONS} =~ /nostrip/) {
	exit;
}

# I could just use `file $_[0]`, but this is safer
sub get_file_type {
	my $file=shift;
	open (FILE, '-|') # handle all filenames safely
		|| exec('file', $file)
		|| die "can't exec file: $!";
	my $type=<FILE>;
	close FILE;
	return $type;
}

# Check if a file is an elf binary, shared library, or static library,
# for use by File::Find. It'll fill the following 3 arrays with anything
# it finds:
my (@shared_libs, @executables, @static_libs);
sub testfile {
	return if -l $_ or -d $_; # Skip directories and symlinks always.

	# See if we were asked to exclude this file.
	# Note that we have to test on the full filename, including directory.
	my $fn="$File::Find::dir/$_";
	foreach my $f (@{$dh{EXCLUDE}}) {
		return if ($fn=~m/\Q$f\E/);
	}

	# Does its filename look like a shared library?
	if (m/.*\.so.*?/) {
		# Ok, do the expensive test.
		my $type=get_file_type($_);
		if ($type=~m/.*ELF.*shared.*/) {
			push @shared_libs, $fn;
			return;
		}
	}
	
	# Is it executable? -x isn't good enough, so we need to use stat.
	my (undef,undef,$mode,undef)=stat(_);
	if ($mode & 0111) {
		# Ok, expensive test.
		my $type=get_file_type($_);
		if ($type=~m/.*ELF.*executable.*/) {
			push @executables, $fn;
			return;
		}
	}
	
	# Is it a static library, and not a debug library?
	if (m/lib.*\.a$/ && ! m/.*_g\.a$/) {
		push @static_libs, $fn;
		return;
	}
}

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

	find(\&testfile,$tmp);

	foreach (@shared_libs) {
		# Note that all calls to strip on shared libs
		# *must* inclde the --strip-unneeded.
		doit("strip","--remove-section=.comment",
			"--remove-section=.note","--strip-unneeded",$_);
	}
	
	foreach (@executables) {
		doit("strip","--remove-section=.comment",
			"--remove-section=.note",$_);
	}

	foreach (@static_libs) {
		doit("strip","--strip-debug",$_);
	}
}

=head1 SEE ALSO

L<debhelper(1)>

This program is a part of debhelper.

=head1 AUTHOR

Joey Hess <joeyh@debian.org>

=cut
