#!/usr/bin/perl use Getopt::Long; use File::Temp qw'tempdir'; use File::Basename; use File::Spec; use strict; sub dllname($;$); my $static; my $inverse; my @exclude; my ($cpu, $ar, $as, $nm, $objcopy); GetOptions('exclude=s'=>\@exclude, 'static!'=>\$static, 'v!'=>\$inverse, 'cpu=s'=>\$cpu, 'ar=s'=>\$ar, 'as=s'=>\$as,'nm=s'=>\$nm, 'objcopy=s'=>\$objcopy); $_ = File::Spec->rel2abs($_) for @ARGV; my $libdll = shift; my $lib = pop; my $uscore = ($cpu eq 'x86_64' ? undef : '_'); (my $iname = basename $lib) =~ s/\.a$//o; $iname = $uscore . $iname . '_dll_iname'; open my $nm_fd, '-|', $nm, '-Apg', '--defined-only', @ARGV, $libdll or die "$0: execution of $nm for object files failed - $!\n"; my %match_syms = (); my $symfiles = (); my $lastfn; my %extract = (); my $exclude_regex = @exclude ? join('|', @exclude) : '\\UnLiKeLy//'; $exclude_regex = qr/$exclude_regex/; my $dllname; while (<$nm_fd>) { study; if (/ I _?(.*)_dll_iname/o) { $dllname = $1; } else { my ($file, $member, $symbol) = m%^([^:]*):([^:]*(?=:))?.* T (.*)%o; next if !defined($symbol) || $symbol =~ $exclude_regex; if ($file ne $libdll) { $match_syms{$symbol} = 1; } elsif ($match_syms{$symbol} ? !$inverse : $inverse) { $extract{$member} = 1; } } } close $nm_fd; %extract or die "$0: couldn't find symbols for $lib\n"; my $dir = tempdir(CLEANUP => 1); chdir $dir; # print join(' ', '+', $ar, 'x', sort keys %extract), "\n"; my $res = system $ar, 'x', $libdll, sort keys %extract; die "$0: $ar extraction exited with non-zero status\n" if $res; unlink $lib; # Add a dummy .idata object for libtool so that it will think # this library is an import library. my $iname_o = 'd000000.o'; $extract{$iname_o} = 1; open my $as_fd, '|-', $as, '-R', '-o', $iname_o, "-"; print $as_fd <