From bbbad3d8a33388ff3ecb1815addb43479b9a1e95 Mon Sep 17 00:00:00 2001
From: David Rowley <dgrowley@gmail.com>
Date: Tue, 27 Jul 2021 22:45:08 +1200
Subject: [PATCH v10 4/4] Remove some special cases from MSVC build scripts

Here we add additional parsing of Makefiles to determine when to add
references to libpgport and libpgcommon.  We also remove the need for
adding the current contrib_extrasource by adding very basic Makefile rules
which add .l and .y files when they exist for a given .o file in the
Makefile.
---
 src/tools/msvc/Mkvcbuild.pm | 71 +++++++++++++++++++++++++++++++------
 src/tools/msvc/Project.pm   | 38 ++++++++++++++++++++
 2 files changed, 99 insertions(+), 10 deletions(-)

diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 06b8525218..019731ba3f 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -36,16 +36,12 @@ my @unlink_on_exit;
 
 # Set of variables for modules in contrib/ and src/test/modules/
 my $contrib_defines = {};
-my @contrib_uselibpq =
-  ('dblink', 'oid2name', 'postgres_fdw', 'vacuumlo', 'libpq_pipeline');
-my @contrib_uselibpgport   = ('libpq_pipeline', 'oid2name', 'vacuumlo');
-my @contrib_uselibpgcommon = ('libpq_pipeline', 'oid2name', 'vacuumlo');
-my $contrib_extralibs     = { 'libpq_pipeline' => ['ws2_32.lib'] };
-my $contrib_extraincludes = {};
-my $contrib_extrasource   = {
-	'cube' => [ 'contrib/cube/cubescan.l', 'contrib/cube/cubeparse.y' ],
-	'seg'  => [ 'contrib/seg/segscan.l',   'contrib/seg/segparse.y' ],
-};
+my @contrib_uselibpq = ();
+my @contrib_uselibpgport   = ('libpq_pipeline');
+my @contrib_uselibpgcommon = ('libpq_pipeline');
+my $contrib_extralibs      = { 'libpq_pipeline' => ['ws2_32.lib'] };
+my $contrib_extraincludes  = {};
+my $contrib_extrasource    = {};
 my @contrib_excludes = (
 	'bool_plperl',      'commit_ts',
 	'hstore_plperl',    'hstore_plpython',
@@ -1010,6 +1006,61 @@ sub AddContrib
 					$proj->AddDefine($1);
 				}
 			}
+			elsif ($flag =~ /^-I(.*)$/)
+			{
+				if ($1 eq '$(libpq_srcdir)')
+				{
+					foreach my $proj (@projects)
+					{
+						$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->AddFileAndAdditionalFiles("$subdir/$n/$file");
+				}
+			}
 		}
 	}
 
diff --git a/src/tools/msvc/Project.pm b/src/tools/msvc/Project.pm
index f1c93a3fa3..e1f1b054ba 100644
--- a/src/tools/msvc/Project.pm
+++ b/src/tools/msvc/Project.pm
@@ -51,6 +51,16 @@ sub AddFile
 	return;
 }
 
+sub AddFileAndAdditionalFiles
+{
+	my ($self, $filename) = @_;
+	if ($self->FindAndAddAdditionalFiles($filename) != 1)
+	{
+		$self->{files}->{$filename} = 1;
+	}
+	return;
+}
+
 sub AddFiles
 {
 	my $self = shift;
@@ -63,6 +73,34 @@ sub AddFiles
 	return;
 }
 
+# Handle special Makefile rules by searching for other files which exist with
+# the same name but a different file extension and add those files too.
+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)
+			{
+				# Add file and recursively search for others
+				$self->AddFileAndAdditionalFiles($file);
+				return 1;
+			}
+		}
+	}
+	return 0;
+}
+
 sub ReplaceFile
 {
 	my ($self, $filename, $newname) = @_;
-- 
2.21.0.windows.1

