From 70df2df1cc89e69e31b31b6aa0d65fd72935af38 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Mon, 19 Sep 2022 15:34:50 -0700 Subject: [PATCH] Extend gendef.pl in preparation for meson 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.rgikv3qn74ypnnbb@awork3.anarazel.de Discussion: https://postgr.es/m/7dae5979-c6c0-cec5-7a36-76a85aa8053d@enterprisedb.com --- src/tools/msvc/MSBuildProject.pm | 4 +- src/tools/msvc/gendef.pl | 67 ++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/src/tools/msvc/MSBuildProject.pm b/src/tools/msvc/MSBuildProject.pm index 594729ceb7..58590fdac2 100644 --- a/src/tools/msvc/MSBuildProject.pm +++ b/src/tools/msvc/MSBuildProject.pm @@ -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 } diff --git a/src/tools/msvc/gendef.pl b/src/tools/msvc/gendef.pl index b4af3dea81..d6bed1ce15 100644 --- a/src/tools/msvc/gendef.pl +++ b/src/tools/msvc/gendef.pl @@ -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";