| #!/usr/bin/perl |
| use strict; |
| use Cwd; |
| use Getopt::Long; |
| use File::Temp qw/tempdir/; |
| use File::Basename; |
| |
| sub xsystem(@); |
| |
| my @exclude = (); |
| my @library = (); |
| my $ar; |
| our $x; |
| GetOptions('exclude=s'=>\@exclude, 'library=s'=>\@library, 'ar=s'=>\$ar, 'x!'=>\$x); |
| |
| die "$0: must specify --ar\n" unless defined $ar; |
| my $lib = shift or die "$0: missing lib argument\nusage: $0 lib [map-file]\n"; |
| $lib = Cwd::abs_path($lib); |
| |
| my %excludes = map {($_, 1)} @exclude; |
| my $libraries = join('|', map {quotemeta} @library); |
| |
| my %sources = (); |
| while (<>) { |
| my ($source, $file, $absfile); |
| if (m%^($libraries)\(([^)]*)\)%o) { |
| $source = $1; |
| $absfile = $file = $2; |
| } elsif (/^LOAD\s+(.*\.o)$/o) { |
| $source = '.'; |
| $file = $1; |
| $absfile = Cwd::abs_path($file); |
| } else { |
| next; |
| } |
| push @{$sources{$source}}, $absfile unless $excludes{$file} || $excludes{$source}; |
| } |
| |
| my $here = getcwd(); |
| my $dir = tempdir(CLEANUP=>1); |
| chdir $dir; |
| my @files = (); |
| for (sort keys %sources) { |
| if ($_ eq '.') { |
| xsystem '/bin/cp', '-a', @{$sources{$_}}, '.'; |
| } else { |
| xsystem $ar, 'x', $_, @{$sources{$_}}, '.'; |
| } |
| push @files, map {basename($_)} @{$sources{$_}}; |
| } |
| |
| unlink $lib; |
| xsystem $ar, 'crs', $lib, sort @files; |
| exit 0; |
| |
| sub xsystem(@) { |
| print join(' ', 'x', @_), "\n" if $x; |
| system(@_) == 0 or die "$0: $_[0] $_[1] $_[2]... exited with non-zero status\n"; |
| } |
| |
| END { |
| chdir '/tmp'; # Allow $dir directory removal on Windows |
| } |