#!/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 }