OSDN Git Service

Rename cygWFMO to cygwait throughout and use the magic of polymorphism to "wait
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / speclib
1 #!/usr/bin/perl
2 use Getopt::Long;
3 use File::Temp qw'tempdir';
4 use File::Basename;
5 use File::Spec;
6 use strict;
7
8 sub dllname($;$);
9
10 my $static;
11 my $inverse;
12 my @exclude;
13
14 my ($ar, $as, $nm, $objcopy);
15 GetOptions('exclude=s'=>\@exclude, 'static!'=>\$static, 'v!'=>\$inverse,
16            'ar=s'=>\$ar, 'as=s'=>\$as,'nm=s'=>\$nm, 'objcopy=s'=>\$objcopy);
17
18 $_ = File::Spec->rel2abs($_) for @ARGV;
19
20 my $libdll = shift;
21 my $lib =  pop;
22 (my $iname = basename $lib) =~ s/\.a$//o;
23 $iname = '_' . $iname . '_dll_iname';
24
25 open my $nm_fd, '-|', $nm, '-Apg', '--defined-only', @ARGV, $libdll or
26   die "$0: execution of $nm for object files failed - $!\n";
27
28 my %match_syms = ();
29 my $symfiles = ();
30 my $lastfn;
31 my %extract = ();
32 my $exclude_regex = @exclude ? join('|', @exclude) : '\\UnLiKeLy//';
33 $exclude_regex = qr/$exclude_regex/;
34 my $dllname;
35 while (<$nm_fd>) {
36     study;
37     if (/ I _(.*)_dll_iname/o) {
38         $dllname = $1;
39     } else {
40         my ($file, $member, $symbol) = m%^([^:]*):([^:]*(?=:))?.* T (.*)%o;
41         next if !defined($symbol) || $symbol =~ $exclude_regex;
42         if ($file ne $libdll) {
43              $match_syms{$symbol} = 1;
44          } elsif ($match_syms{$symbol} ? !$inverse : $inverse) {
45              $extract{$member} = 1;
46          }
47     }
48 }
49 close $nm_fd;
50    
51
52 %extract or die "$0: couldn't find symbols for $lib\n";
53
54 my $dir = tempdir(CLEANUP => 1);
55
56 chdir $dir;
57 # print join(' ', '+', $ar, 'x', sort keys %extract), "\n";
58 my $res = system $ar, 'x', $libdll, sort keys %extract;
59 die "$0: $ar extraction exited with non-zero status\n" if $res;
60 unlink $lib;
61
62 # Add a dummy .idata object for libtool so that it will think
63 # this library is an import library.
64 my $iname_o = 'd000000.o';
65 $extract{$iname_o} = 1;
66 open my $as_fd, '|-', $as, '-R', '-o', $iname_o, "-";
67 print $as_fd <<EOF;
68         .section .idata\$7
69 .global $iname
70 $iname: .asciz "$dllname.dll"
71 EOF
72 close $as_fd or exit 1;
73 system $objcopy, '-j', '.idata$7', $iname_o;
74
75 $res = system $ar, 'crus', $lib, sort keys %extract;
76 unlink keys %extract;
77 die "$0: ar creation of $lib exited with non-zero status\n" if $res;
78 exit 0;
79
80 END {
81     chdir '/tmp';       # Allow $dir directory removal on Windows
82 }