Thank you for having another look at this.
On Tue, 12 Jan 2021 at 20:18, Michael Paquier <[email protected]> wrote:
>
> On Wed, Dec 30, 2020 at 10:07:29AM +1300, David Rowley wrote:
> > -#ifdef LOWER_NODE
> > +/*
> > + * Below we ignore the fact that LOWER_NODE is defined when compiling with
> > + * MSVC. The reason for this is that earlier versions of the MSVC build
> > + * scripts failed to define LOWER_NODE. More recent version of the MSVC
> > + * build scripts parse makefiles which results in LOWER_NODE now being
> > + * defined. We check for _MSC_VER here so as not to break pg_upgrade when
> > + * upgrading from versions MSVC versions where LOWER_NODE was not defined.
> > + */
> > +#if defined(LOWER_NODE) && !defined(_MSC_VER)
> > #include <ctype.h>
> > #define TOLOWER(x) tolower((unsigned char) (x))
> > #else
>
> While on it, do you think that it would be more readable if we remove
> completely LOWER_NODE and use only a check based on _MSC_VER for those
> two files in ltree? This could also be handled as a separate change.
I'm hesitant to touch that. If anyone is running an instance compiled
with a non-default LOWER_NODE then we might give them some trouble if
they pg_upgrade their database later.
> > + foreach my $line (split /\n/, $mf)
> > + {
> > + if ($line =~ /^[A-Za-z0-9_]*\.o:\s(.*)/)
> > + {
> > + foreach my $file (split /\s+/, $1)
> > + {
> > + foreach my $proj (@projects)
> > + {
> > +
> > $proj->AddFileConditional("$subdir/$n/$file");
> > + }
> > + }
> > + }
> > + }
> Looking closer at this change, I don't think that this is completely
> correct and that could become a trap. This is adding quite a bit of
> complexity to take care of contrib_extrasource getting empty, and it
> actually overlaps with the handling of OBJS done in AddDir(), no?
hmm. I'm not quite sure if I know what you mean by "trap" here.
contrib/cube/Makefile has an example of what this is trying to catch:
# cubescan is compiled as part of cubeparse
cubeparse.o: cubescan.c
I don't really see what other options there are apart from just not
get rid of $contrib_extrasource.
Can you give an example of what sort of scenario you've got in mind
where it'll cause issues?
I've attached a rebased patch.
David
diff --git a/contrib/ltree/crc32.c b/contrib/ltree/crc32.c
index 8fed3346e8..b035706c05 100644
--- a/contrib/ltree/crc32.c
+++ b/contrib/ltree/crc32.c
@@ -9,7 +9,15 @@
#include "postgres.h"
-#ifdef LOWER_NODE
+/*
+ * Below we ignore the fact that LOWER_NODE is defined when compiling with
+ * MSVC. The reason for this is that earlier versions of the MSVC build
+ * scripts failed to define LOWER_NODE. More recent version of the MSVC
+ * build scripts parse makefiles which results in LOWER_NODE now being
+ * defined. We check for _MSC_VER here so as not to break pg_upgrade when
+ * upgrading from versions MSVC versions where LOWER_NODE was not defined.
+ */
+#if defined(LOWER_NODE) && !defined(_MSC_VER)
#include <ctype.h>
#define TOLOWER(x) tolower((unsigned char) (x))
#else
diff --git a/contrib/ltree/ltree.h b/contrib/ltree/ltree.h
index dc68a0c212..8c10384503 100644
--- a/contrib/ltree/ltree.h
+++ b/contrib/ltree/ltree.h
@@ -90,7 +90,15 @@ typedef struct
#define LQL_NOT 0x10 /* level has '!' (NOT) prefix */
#define LQL_COUNT 0x20 /* level is non-'*' and has repeat
counts */
-#ifdef LOWER_NODE
+/*
+ * Below we ignore the fact that LOWER_NODE is defined when compiling with
+ * MSVC. The reason for this is that earlier versions of the MSVC build
+ * scripts failed to define LOWER_NODE. More recent version of the MSVC
+ * build scripts parse makefiles which results in LOWER_NODE now being
+ * defined. We check for _MSC_VER here so as not to break pg_upgrade when
+ * upgrading from versions MSVC versions where LOWER_NODE was not defined.
+ */
+#if defined(LOWER_NODE) && !defined(_MSC_VER)
#define FLG_CANLOOKSIGN(x) ( ( (x) & ( LQL_NOT | LVAR_ANYEND | LVAR_SUBLEXEME
) ) == 0 )
#else
#define FLG_CANLOOKSIGN(x) ( ( (x) & ( LQL_NOT | LVAR_ANYEND | LVAR_SUBLEXEME
| LVAR_INCASE ) ) == 0 )
diff --git a/src/tools/msvc/MSBuildProject.pm b/src/tools/msvc/MSBuildProject.pm
index ebb169e201..2cf3fee65d 100644
--- a/src/tools/msvc/MSBuildProject.pm
+++ b/src/tools/msvc/MSBuildProject.pm
@@ -109,15 +109,13 @@ sub AddDefine
sub WriteReferences
{
my ($self, $f) = @_;
-
- my @references = @{ $self->{references} };
-
- if (scalar(@references))
+ # Add referenced projects, if any exist.
+ if (scalar(keys % { $self->{references} }) > 0)
{
print $f <<EOF;
<ItemGroup>
EOF
- foreach my $ref (@references)
+ foreach my $ref (values % { $self->{references} } )
{
print $f <<EOF;
<ProjectReference Include="$ref->{name}$ref->{filenameExtension}">
@@ -310,11 +308,12 @@ sub WriteItemDefinitionGroup
my $targetmachine =
$self->{platform} eq 'Win32' ? 'MachineX86' : 'MachineX64';
- my $includes = $self->{includes};
- unless ($includes eq '' or $includes =~ /;$/)
+ my $includes = "";
+ foreach my $inc (keys %{ $self->{includes} } )
{
- $includes .= ';';
+ $includes .= $inc . ";";
}
+
print $f <<EOF;
<ItemDefinitionGroup
Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'">
<ClCompile>
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 49614106dc..fd6e32c9ec 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -32,16 +32,13 @@ my $libpq;
my @unlink_on_exit;
# Set of variables for modules in contrib/ and src/test/modules/
-my $contrib_defines = { 'refint' => 'REFINT_VERBOSE' };
-my @contrib_uselibpq = ('dblink', 'oid2name', 'postgres_fdw', 'vacuumlo');
-my @contrib_uselibpgport = ('oid2name', 'vacuumlo');
-my @contrib_uselibpgcommon = ('oid2name', 'vacuumlo');
+my $contrib_defines = {};
+my @contrib_uselibpq = ();
+my @contrib_uselibpgport = ();
+my @contrib_uselibpgcommon = ();
my $contrib_extralibs = undef;
-my $contrib_extraincludes = { 'dblink' => ['src/backend'] };
-my $contrib_extrasource = {
- 'cube' => [ 'contrib/cube/cubescan.l', 'contrib/cube/cubeparse.y' ],
- 'seg' => [ 'contrib/seg/segscan.l', 'contrib/seg/segparse.y' ],
-};
+my $contrib_extraincludes = {};
+my $contrib_extrasource = {};
my @contrib_excludes = (
'bool_plperl', 'commit_ts',
'hstore_plperl', 'hstore_plpython',
@@ -927,8 +924,12 @@ sub AddTransformModule
# Add PL dependencies
$p->AddIncludeDir($pl_src);
$p->AddReference($pl_proj);
- $p->AddIncludeDir($pl_proj->{includes});
- foreach my $pl_lib (@{ $pl_proj->{libraries} })
+ foreach my $inc (keys %{ $pl_proj->{includes} } )
+ {
+ $p->AddIncludeDir($inc);
+ }
+
+ foreach my $pl_lib (keys %{ $pl_proj->{libraries} } )
{
$p->AddLibrary($pl_lib);
}
@@ -937,8 +938,11 @@ sub AddTransformModule
if ($type_proj)
{
$p->AddIncludeDir($type_src);
- $p->AddIncludeDir($type_proj->{includes});
- foreach my $type_lib (@{ $type_proj->{libraries} })
+ foreach my $inc (keys %{ $type_proj->{includes} } )
+ {
+ $p->AddIncludeDir($inc);
+ }
+ foreach my $type_lib (keys %{ $type_proj->{libraries} } )
{
$p->AddLibrary($type_lib);
}
@@ -954,6 +958,7 @@ sub AddContrib
my $subdir = shift;
my $n = shift;
my $mf = Project::read_file("$subdir/$n/Makefile");
+ my @projects;
if ($mf =~ /^MODULE_big\s*=\s*(.*)$/mg)
{
@@ -961,6 +966,7 @@ sub AddContrib
my $proj = $solution->AddProject($dn, 'dll', 'contrib',
"$subdir/$n");
$proj->AddReference($postgres);
AdjustContribProj($proj);
+ push @projects, $proj;
}
elsif ($mf =~ /^MODULES\s*=\s*(.*)$/mg)
{
@@ -972,18 +978,90 @@ sub AddContrib
$proj->AddFile("$subdir/$n/$filename");
$proj->AddReference($postgres);
AdjustContribProj($proj);
+ push @projects, $proj;
}
}
elsif ($mf =~ /^PROGRAM\s*=\s*(.*)$/mg)
{
my $proj = $solution->AddProject($1, 'exe', 'contrib',
"$subdir/$n");
AdjustContribProj($proj);
+ push @projects, $proj;
}
else
{
croak "Could not determine contrib module type for $n\n";
}
+ # Process custom compiler flags
+ if ($mf =~ /^PG_CPPFLAGS\s*=\s*(.*)$/mg || $mf =~
/^override\s*CPPFLAGS\s*(?:[\+\:])?=\s*(.*)$/mg)
+ {
+ foreach my $flag (split /\s+/, $1)
+ {
+ if ($flag =~ /^-D(.*)$/)
+ {
+ foreach my $proj (@projects)
+ {
+ $proj->AddDefine($1);
+ }
+ }
+ elsif ($flag =~ /^-I(.*)$/)
+ {
+ foreach my $proj (@projects)
+ {
+ if ($1 eq '$(libpq_srcdir)')
+ {
+
$proj->AddIncludeDir('src\interfaces\libpq');
+ $proj->AddReference($libpq);
+ }
+ }
+ }
+ }
+ }
+
+ if ($mf =~ /^SHLIB_LINK_INTERNAL\s*=\s*(.*)$/mg)
+ {
+ foreach my $lib (split /\s+/, $1)
+ {
+ if ($lib eq '$(libpq)')
+ {
+ foreach my $proj (@projects)
+ {
+
$proj->AddIncludeDir('src\interfaces\libpq');
+ $proj->AddReference($libpq);
+ }
+ }
+ }
+ }
+
+ if ($mf =~ /^PG_LIBS_INTERNAL\s*=\s*(.*)$/mg)
+ {
+ foreach my $lib (split /\s+/, $1)
+ {
+ if ($lib eq '$(libpq_pgport)')
+ {
+ foreach my $proj (@projects)
+ {
+ $proj->AddReference($libpgport);
+ $proj->AddReference($libpgcommon);
+ }
+ }
+ }
+ }
+
+ foreach my $line (split /\n/, $mf)
+ {
+ if ($line =~ /^[A-Za-z0-9_]*\.o:\s(.*)/)
+ {
+ foreach my $file (split /\s+/, $1)
+ {
+ foreach my $proj (@projects)
+ {
+
$proj->AddFileConditional("$subdir/$n/$file");
+ }
+ }
+ }
+ }
+
# Are there any output data files to build?
GenerateContribSqlFiles($n, $mf);
return;
diff --git a/src/tools/msvc/Project.pm b/src/tools/msvc/Project.pm
index 20f79b382b..ad9e4b6dcc 100644
--- a/src/tools/msvc/Project.pm
+++ b/src/tools/msvc/Project.pm
@@ -24,10 +24,10 @@ sub _new
type => $type,
guid => $^O eq "MSWin32" ? Win32::GuidGen() :
'FAKE',
files => {},
- references => [],
- libraries => [],
+ references => {},
+ libraries => {},
suffixlib => [],
- includes => '',
+ includes => {},
prefixincludes => '',
defines => ';',
solution => $solution,
@@ -42,12 +42,25 @@ sub _new
sub AddFile
{
- my ($self, $filename) = @_;
+ my ($self, $filename, $alwaysAddOriginal) = @_;
+ FindAndAddAdditionalFiles($self, $filename);
+ # Add the original file regardless to the return value of
+ # FindAndAddAdditionalFiles
$self->{files}->{$filename} = 1;
return;
}
+sub AddFileConditional
+{
+ my ($self, $filename) = @_;
+ if (FindAndAddAdditionalFiles($self, $filename) != 1)
+ {
+ $self->{files}->{$filename} = 1;
+ }
+ return;
+}
+
sub AddFiles
{
my $self = shift;
@@ -55,11 +68,39 @@ sub AddFiles
while (my $f = shift)
{
- $self->{files}->{ $dir . "/" . $f } = 1;
+ AddFile($self, $dir . "/" . $f, 1);
}
return;
}
+# Handle makefile rules for when file to be added to the project
+# does not exist. Returns 1 when the original file add should be
+# skipped.
+sub FindAndAddAdditionalFiles
+{
+ my $self = shift;
+ my $fname = shift;
+ $fname =~ /(.*)(\.[^.]+)$/;
+ my $filenoext = $1;
+ my $fileext = $2;
+
+ # For .c files, check if either a .l or .y file of the same name
+ # exists and add that too.
+ if ($fileext eq ".c")
+ {
+ for my $ext (".l", ".y")
+ {
+ my $file = $filenoext . $ext;
+ if (-e $file)
+ {
+ AddFileConditional($self, $file);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
sub ReplaceFile
{
my ($self, $filename, $newname) = @_;
@@ -74,14 +115,14 @@ sub ReplaceFile
if ($file eq $filename)
{
delete $self->{files}{$file};
- $self->{files}{$newname} = 1;
+ AddFile($self, $newname);
return;
}
}
elsif ($file =~ m/($re)/)
{
delete $self->{files}{$file};
- $self->{files}{"$newname/$filename"} = 1;
+ AddFile($self, "$newname/$filename");
return;
}
}
@@ -121,7 +162,8 @@ sub AddReference
while (my $ref = shift)
{
- push @{ $self->{references} }, $ref;
+ my $name = $ref->{name};
+ $self->{references}->{$name} = $ref;
$self->AddLibrary(
"__CFGNAME__/" . $ref->{name} . "/" . $ref->{name} .
".lib");
}
@@ -138,7 +180,7 @@ sub AddLibrary
$lib = '"' . $lib . """;
}
- push @{ $self->{libraries} }, $lib;
+ $self->{libraries}->{$lib} = 1;
if ($dbgsuffix)
{
push @{ $self->{suffixlib} }, $lib;
@@ -148,13 +190,12 @@ sub AddLibrary
sub AddIncludeDir
{
- my ($self, $inc) = @_;
+ my ($self, $incstr) = @_;
- if ($self->{includes} ne '')
+ foreach my $inc (split(/;/, $incstr))
{
- $self->{includes} .= ';';
+ $self->{includes}->{$inc} = 1;
}
- $self->{includes} .= $inc;
return;
}
@@ -256,11 +297,11 @@ sub AddDir
if ($f =~ /^\$\(top_builddir\)\/(.*)/)
{
$f = $1;
- $self->{files}->{$f} = 1;
+ AddFile($self, $f);
}
else
{
- $self->{files}->{"$reldir/$f"} = 1;
+ AddFile($self, "$reldir/$f");
}
}
$mf =~ s{OBJS[^=]*=\s*(.*)$}{}m;
@@ -397,7 +438,7 @@ sub GetAdditionalLinkerDependencies
my ($self, $cfgname, $separator) = @_;
my $libcfg = (uc $cfgname eq "RELEASE") ? "MD" : "MDd";
my $libs = '';
- foreach my $lib (@{ $self->{libraries} })
+ foreach my $lib (keys %{ $self->{libraries} })
{
my $xlib = $lib;
foreach my $slib (@{ $self->{suffixlib} })