aboutsummaryrefslogtreecommitdiff
path: root/winsup/cygwin/speclib
blob: 37ab5da5108834e93fea16a0f36cab63d8baee1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/usr/bin/perl
use Getopt::Long;
use File::Temp;
use File::Basename;
use File::Spec;
use strict;

sub dllname($;$);

my $static;
my $inverse;
my @exclude;

my ($ar, $as, $nm, $objcopy);
GetOptions('exclude=s'=>\@exclude, 'static!'=>\$static, 'v!'=>\$inverse,
	   'ar=s'=>\$ar, 'as=s'=>\$as,'nm=s'=>\$nm, 'objcopy=s'=>\$objcopy);

$_ = File::Spec->rel2abs($_) for @ARGV;

my $libdll = shift;
my $lib =  pop;

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/;
while (<$nm_fd>) {
    study;
    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 = File::Temp->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;
$res = system $ar, 'crus', $lib, sort keys %extract;
unlink keys %extract;
die "$0: ar creation of $lib exited with non-zero status\n" if $res;
exit 0;