use strict;
use warnings;
-use List::Util qw(max);
+use List::Util qw(min);
+use Getopt::Long;
my @def;
sub writedef
{
- my ($deffile, $platform, $def) = @_;
+ my ($deffile, $arch, $def) = @_;
open(my $fh, '>', $deffile) || die "Could not write to $deffile\n";
print $fh "EXPORTS\n";
foreach my $f (sort keys %{$def})
# Strip the leading underscore for win32, but not x64
$f =~ s/^_//
- unless ($platform eq "x64");
+ unless ($arch eq "x86_64");
# Emit just the name if it's a function symbol, or emit the name
# decorated with the DATA option for variables.
sub usage
{
- die( "Usage: gendef.pl
\n"
- . " modulepath: path to dir with obj files, no trailing slash"
- . " platform: Win32 | x64");
+ die("Usage: gendef.pl --arch
--deffile --tempdir files-or-directories\n"
+ . " arch: x86 | x86_64\n"
+ . " deffile: path of the generated file\n"
+ . " tempdir: directory for temporary files\n"
+ . " files or directories: object files or directory containing object files\n"
+ );
}
-usage()
- unless scalar(@ARGV) == 2
- && ( ($ARGV[0] =~ /\\([^\\]+$)/)
- && ($ARGV[1] eq 'Win32' || $ARGV[1] eq 'x64'));
-my $defname = uc $1;
-my $deffile = "$ARGV[0]/$defname.def";
-my $platform = $ARGV[1];
+my $arch;
+my $deffile;
+my $tempdir = '.';
+
+GetOptions(
+ 'arch:s' => \$arch,
+ 'deffile:s' => \$deffile,
+ 'tempdir:s' => \$tempdir,) or usage();
+
+usage("arch: $arch")
+ unless ($arch eq 'x86' || $arch eq 'x86_64');
+
+my @files;
+
+foreach my $in (@ARGV)
+{
+ if (-d $in)
+ {
+ push @files, glob "$in/*.obj";
+ }
+ else
+ {
+ push @files, $in;
+ }
+}
# if the def file exists and is newer than all input object files, skip
# its creation
if (-f $deffile
- && (-M $deffile > max(map { -M } <$ARGV[0]/*.obj>)))
+ && (-M $deffile < min(map { -M } @files)))
{
- print "Not re-generating $defname.DEF, file already exists.\n";
+ print "Not re-generating $deffile, file already exists.\n";
exit(0);
}
-print "Generating $defname.DEF from directory $ARGV[0], platform $platform\n";
+print "Generating $deffile in tempdir $tempdir\n";
my %def = ();
-my $symfile = "$ARGV[0]/all.sym";
-my $tmpfile = "$ARGV[0]/tmp.sym";
-system("dumpbin /symbols /out:$tmpfile $ARGV[0]/*.obj >NUL")
- && die "Could not call dumpbin";
+my $symfile = "$tempdir/all.sym";
+my $tmpfile = "$tempdir/tmp.sym";
+mkdir($tempdir) unless -d $tempdir;
+
+my $cmd = "dumpbin /nologo /symbols /out:$tmpfile " . join(' ', @files);
+
+system($cmd) && die "Could not call dumpbin";
rename($tmpfile, $symfile);
extract_syms($symfile, \%def);
print "\n";
-writedef($deffile, $platform, \%def);
+writedef($deffile, $arch, \%def);
print "Generated " . scalar(keys(%def)) . " symbols\n";