From fd19f6f5f0c833a28e2db64d745450bdea640c36 Mon Sep 17 00:00:00 2001
From: David Rowley <dgrowley@gmail.com>
Date: Tue, 27 Jul 2021 22:45:08 +1200
Subject: [PATCH v9 6/6] 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 f344ac661e..f1cb923a75 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',
@@ -1017,6 +1013,61 @@ sub AddContrib
 					$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->AddFileAndAdditionalFiles("$subdir/$n/$file");
+				}
+			}
 		}
 	}
 
diff --git a/src/tools/msvc/Project.pm b/src/tools/msvc/Project.pm
index f633ec90af..204d3cea1b 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 (FindAndAddAdditionalFiles($self, $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
+				AddFileAndAdditionalFiles($self, $file);
+				return 1;
+			}
+		}
+	}
+	return 0;
+}
+
 sub ReplaceFile
 {
 	my ($self, $filename, $newname) = @_;
-- 
2.21.0.windows.1

