Extend gendef.pl in preparation for meson
authorAndres Freund
Mon, 19 Sep 2022 22:34:50 +0000 (15:34 -0700)
committerAndres Freund
Mon, 19 Sep 2022 22:39:35 +0000 (15:39 -0700)
The main issue with using gendef.pl as-is for meson is that with meson the
filenames are a bit longer, exceeding the max commandline length when calling
dumpbin with all objects. As it's easier to pass in a library anyway, do so.

The .def file location, input and temporary file location need to be tunable
as well.

This also fixes a bug in gendef.pl: The logic when to regenerate was broken
and never avoid regenerating.

Author: Andres Freund 
Reviewed-By: Peter Eisentraut
Discussion: https://postgr.es/m/20220809071055[email protected]
Discussion: https://postgr.es/m/7dae5979-c6c0-cec5-7a36-76a85aa8053d@enterprisedb.com

src/tools/msvc/MSBuildProject.pm
src/tools/msvc/gendef.pl

index 594729ceb7d8fecbf22bb7f93cfa33c577c06732..58590fdac298c6120b664918c2ce6528a8307e6a 100644 (file)
@@ -312,6 +312,8 @@ sub WriteItemDefinitionGroup
 
    my $targetmachine =
      $self->{platform} eq 'Win32' ? 'MachineX86' : 'MachineX64';
+   my $arch =
+     $self->{platform} eq 'Win32' ? 'x86' : 'x86_64';
 
    my $includes = join ';', @{ $self->{includes} }, "";
 
@@ -380,7 +382,7 @@ EOF
        print $f <
     
       Generate DEF file
-      perl src\\tools\\msvc\\gendef.pl $cfgname\\$self->{name} $self->{platform}
+      perl src\\tools\\msvc\\gendef.pl --arch $arch --deffile $cfgname\\$self->{name}\\$self->{name}.def $cfgname\\$self->{name}
     
 EOF
    }
index b4af3dea81bd98f8f18dce23f07b568a1a417692..d6bed1ce1512e6ad063e69085c4c4b43cbab58f4 100644 (file)
@@ -3,7 +3,8 @@
 
 use strict;
 use warnings;
-use List::Util qw(max);
+use List::Util qw(min);
+use Getopt::Long;
 
 my @def;
 
@@ -112,7 +113,7 @@ sub extract_syms
 
 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})
@@ -121,7 +122,7 @@ sub writedef
 
        # 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.
@@ -141,40 +142,64 @@ sub writedef
 
 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";