Hi,

On 2022-09-30 15:35:26 -0700, Andres Freund wrote:
> I was thinking of starting at least the following threads / CF entries once a
> few of the remaining things are resolved:
> 
> - PGXS compatibility, plus related autoconf simplification patches
> - pkg-config files for building postgres extensions
> - relative rpath support
> 
> I am a bit on the fence about whether it's worth doing so for:
> 
> - installcheck equivalent
> - precompiled header support (would like it soon, because it reduces
>   compile-test times substantially)
> 
> and, for no really tangible reason, considered
> - resource files generation
> - docs
> - docs dependency
> 
> to be part of this thread / CF entry.
> 
> Now that I think about it more, I am inclined to also push the docs changes to
> a new thread, just for wider visibility.
> 
> I think it'd be ok to commit the docs dependency fix soon, without a separate
> thread, as it really fixes a "build bug".

I've not yet posted these different threads, but I've split up the meson tree
into subtrees corresponding to pretty much the above.


The meson tree now mainly merges those subtrees together. It still directly
contains the xml-tools dependency wrapper (to be merged soon) and the CI
changes (either later or never).

I've attached a revised version of the xml-tools dependency wrapper (0001):
Cleanups, minor error handling improvements, and bit of comment polishing. I'd
welcome review. But as it fixes a build-dependency bug / FIXME, I'm planning
to push it relatively soon otherwise.

0002 fixes libpq's .pc file (static dependencies didn't show up anymore) and
AIX compilation. AIX doesn't yet support link_whole (support was merged into
meson yesterday though). On the way it also improves comments and a bit of
generic infrastructure.  The price for now is that the static libpq is built
separately from the shared one, not reusing any objects. I felt that the
complexity of reusing the objects isn't worth it for now.

Peter, it'd be great if you could have a look at 0002.

0003 mirrors the setup of libpq to the various ecpg libraries. This is a
prerequisite to adding resource files.

0004 adds the resource files


I think after that we could close the CF entry (and create a bunch of followup
entries, as discussed above). Although it somehow seems frivolous to start a
separate thread for "installcheck equivalent" :)

Greetings,

Andres Freund
>From b21850b49a9dd9f4a60eb9c243ba64be61e7e9c0 Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Mon, 3 Oct 2022 18:26:24 -0700
Subject: [PATCH v18 01/22] meson: docs: Add xml{lint,proc} wrapper to collect
 dependencies

meson/ninja do not support specifying dependencies via globs (as those make it
significantly more expensive to check the current build state). Instead
targets should emit dependency information when running that then can be
cheaply re-checked during future builds.

To handle xmllint and xsltproc invocations in the docs, add and use a wrapper
that uses --load-trace to collect dependency information.

Author: Nazir Bilal Yavuz <byavu...@gmail.com>
Author: Andres Freund <and...@anarazel.de>
Discussion: https://postgr.es/m/c5736f70-bb6d-8d25-e35c-e3d886e4e...@enterprisedb.com
---
 doc/src/sgml/meson.build          | 41 ++++++++++++++++-------
 doc/src/sgml/xmltools_dep_wrapper | 54 +++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+), 11 deletions(-)
 create mode 100644 doc/src/sgml/xmltools_dep_wrapper

diff --git a/doc/src/sgml/meson.build b/doc/src/sgml/meson.build
index ba2a261e7a4..65fd6131344 100644
--- a/doc/src/sgml/meson.build
+++ b/doc/src/sgml/meson.build
@@ -2,7 +2,7 @@ docs = []
 alldocs = []
 doc_generated = []
 
-xmllint = find_program(get_option('XMLLINT'), native: true, required: false)
+xmllint_bin = find_program(get_option('XMLLINT'), native: true, required: false)
 
 
 version_sgml = configure_file(
@@ -60,14 +60,23 @@ doc_generated += custom_target('keywords-table.sgml',
 )
 
 # For everything else we need at least xmllint
-if not xmllint.found()
+if not xmllint_bin.found()
   subdir_done()
 endif
 
 pandoc = find_program('pandoc', native: true, required: false)
-xsltproc = find_program(get_option('XSLTPROC'), native: true, required: false)
+xsltproc_bin = find_program(get_option('XSLTPROC'), native: true, required: false)
 fop = find_program('fop', native: true, required: false)
 
+xmltools_wrapper = [
+  python, files('xmltools_dep_wrapper'),
+  '--targetname', '@OUTPUT@', '--depfile', '@DEPFILE@'
+]
+
+xmllint = xmltools_wrapper + [
+  '--tool', xmllint_bin, '--',
+]
+
 # Run validation only once, common to all subsequent targets.  While
 # we're at it, also resolve all entities (that is, copy all included
 # files into one big file).  This helps tools that don't understand
@@ -75,6 +84,7 @@ fop = find_program('fop', native: true, required: false)
 postgres_full_xml = custom_target('postgres-full.xml',
   input: 'postgres.sgml',
   output: 'postgres-full.xml',
+  depfile: 'postgres-full.xml.d',
   command: [xmllint, '--noent', '--valid', '--path', '@OUTDIR@', '-o', '@OUTPUT@', '@INPUT@'],
   depends: doc_generated,
   build_by_default: false,
@@ -86,18 +96,20 @@ alldocs += postgres_full_xml
 #
 # Full documentation as html, text
 #
-if xsltproc.found()
+if xsltproc_bin.found()
   xsltproc_flags = [
     '--stringparam', 'pg.version', pg_version,
     '--param', 'website.stylesheet', '1'
   ]
 
+  xsltproc = xmltools_wrapper + [
+    '--tool', xsltproc_bin, '--',
+  ]
 
-  # FIXME: Should use a wrapper around xsltproc --load-trace to compute a
-  # depfile
   html = custom_target('html',
     input: ['stylesheet.xsl', postgres_full_xml],
     output: 'html',
+    depfile: 'html.d',
     depends: doc_generated,
     command: [xsltproc, '-o', '@OUTDIR@/', xsltproc_flags, '@INPUT@'],
     build_by_default: false,
@@ -110,6 +122,7 @@ if xsltproc.found()
   html_help = custom_target('html_help',
     input: ['stylesheet-hh.xsl', postgres_full_xml],
     output: 'htmlhelp',
+    depfile: 'htmlhelp.d',
     depends: doc_generated,
     command: [xsltproc, '--path', '@OUTDIR@', '-o', '@OUTDIR@/', xsltproc_flags, '@INPUT@'],
     build_by_default: false,
@@ -121,6 +134,7 @@ if xsltproc.found()
   postgres_html = custom_target('postgres.html',
     input: ['stylesheet-html-nochunk.xsl', postgres_full_xml],
     output: 'postgres.html',
+    depfile: 'postgres.html.d',
     depends: doc_generated,
     command: [xsltproc, '--path', '@OUTDIR@', '-o', '@OUTPUT@', xsltproc_flags, '@INPUT@'],
     build_by_default: false,
@@ -144,10 +158,11 @@ endif
 #
 # INSTALL in html, text
 #
-if xsltproc.found()
+if xsltproc_bin.found()
   install_xml = custom_target('INSTALL.xml',
     input: ['standalone-profile.xsl', 'standalone-install.xml'],
     output: 'INSTALL.xml',
+    depfile: 'INSTALL.xml.d',
     depends: doc_generated + [postgres_full_xml],
     command: [xsltproc, '--path', '@OUTDIR@', '-o', '@OUTPUT@', xsltproc_flags, '--xinclude', '@INPUT@'],
     build_by_default: false,
@@ -155,6 +170,7 @@ if xsltproc.found()
   install_html = custom_target('INSTALL.html',
     input: ['stylesheet-text.xsl', install_xml],
     output: 'INSTALL.html',
+    depfile: 'INSTALL.html.d',
     command: [xsltproc, '--path', '@OUTDIR@', '-o', '@OUTPUT@', xsltproc_flags, '@INPUT@'],
     build_by_default: false,
   )
@@ -177,11 +193,12 @@ endif
 #
 # Man pages
 #
-if xsltproc.found()
+if xsltproc_bin.found()
   # FIXME: implement / consider sqlmansectnum logic
   man = custom_target('man',
     input: ['stylesheet-man.xsl', postgres_full_xml],
     output: ['man1', 'man3', 'man7'],
+    depfile: 'man.d',
     depends: doc_generated,
     command: [xsltproc, '--path', '@OUTDIR@', '-o', '@OUTDIR@/', xsltproc_flags, '@INPUT@'],
     build_by_default: false,
@@ -195,17 +212,19 @@ endif
 #
 # Full documentation as PDF
 #
-if fop.found() and xsltproc.found()
+if fop.found() and xsltproc_bin.found()
   xsltproc_fo_flags = xsltproc_flags + ['--stringparam', 'img.src.path', meson.current_source_dir() + '/']
 
   foreach format, detail: {'A4': 'A4', 'US': 'USletter'}
     postgres_x_fo_f = 'postgres-@0@.fo'.format(format)
+    postgres_x_fo_dep = 'postgres-@0@.fo.d'.format(format)
     postgres_x_pdf_f = 'postgres-@0@.pdf'.format(format)
 
     postgres_x_fo = custom_target(postgres_x_fo_f,
       input: ['stylesheet-fo.xsl', postgres_full_xml],
-      output: [postgres_x_fo_f],
+      output: postgres_x_fo_f,
       depends: doc_generated,
+      depfile: postgres_x_fo_dep,
       command: [xsltproc, '--path', '@OUTDIR@/', xsltproc_fo_flags,
                 '--stringparam', 'paper.type', detail,
                 '-o', '@OUTPUT@', '@INPUT@'],
@@ -230,7 +249,7 @@ endif
 # This was previously implemented using dbtoepub - but that doesn't seem to
 # support running in build != source directory (i.e. VPATH builds already
 # weren't supported).
-if pandoc.found() and xsltproc.found()
+if pandoc.found() and xsltproc_bin.found()
   postgres_epub = custom_target('postgres.epub',
     input: postgres_full_xml,
     output: 'postgres.epub',
diff --git a/doc/src/sgml/xmltools_dep_wrapper b/doc/src/sgml/xmltools_dep_wrapper
new file mode 100644
index 00000000000..dd96f784268
--- /dev/null
+++ b/doc/src/sgml/xmltools_dep_wrapper
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+
+# A small wrapper around xmllint and xsltproc that collects dependency
+# information (in gcc's format) using --load-trace.
+
+import argparse
+import re
+import subprocess
+import sys
+
+parser = argparse.ArgumentParser(
+    description='generate dependency file for docs')
+
+parser.add_argument('--targetname', type=str, required=False, nargs='+')
+parser.add_argument('--depfile', type=str, required=False)
+parser.add_argument('--tool', type=str, required=True)
+parser.add_argument('flags', nargs='*')
+
+args = parser.parse_args()
+
+if args.depfile:
+    command = [args.tool, '--load-trace'] + args.flags
+
+    # list of targets that depend on the loaded files we see via --load-trace
+    line_start = ' '.join(args.targetname) + ': '
+
+    # --load-trace flag displays all the documents loaded during the processing
+    # to stderr
+    res = subprocess.run(command, stderr=subprocess.PIPE,
+                         universal_newlines=True)
+
+    line_re = re.compile('^Loaded URL="([^"]+)"')
+    with open(args.depfile, 'w') as f:
+        for line in res.stderr.splitlines():
+            m = re.match(line_re, line)
+
+            # continue to show errors
+            if m is None:
+                print(line, file=sys.stderr)
+                continue
+            # Absolute paths are printed as file://, relative paths as-is. We
+            # don't care about http://, as a) those will be printed even if
+            # resolved locally b) we couldn't have a dependency anyway.
+            fname = m.group(1)
+            if fname.startswith('http://'):
+                continue
+            if fname.startswith('file://'):
+                fname = fname.split('file://')[1]
+            f.write(line_start + fname + '\n')
+else:
+    command = [args.tool] + args.flags
+    res = subprocess.run(command)
+
+exit(res.returncode)
-- 
2.37.3.542.gdd3f6c4cae

>From 984bf68207a97c7bc055f3e2bbd79fd39918bd1b Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Thu, 29 Sep 2022 21:37:48 -0700
Subject: [PATCH v18 02/22] meson: libpq: Revise static / shared library setup

Improvements:
- we don't need -DFRONTEND for libpq anymore since 1d77afefbd1
- the .pc file contents for a static libpq were wrong (referencing
  {pgport, common}_shlib)
- incidentally fixes meson not supporting link_whole on AIX yet
- added explanatory comments

Previously I tried to avoid building libpq's sources twice, once for the
static and once for the shared library. We could still do so, but it's not
clear that it's worth the complication.
---
 src/interfaces/libpq/meson.build | 28 ++++++++++++++++++----------
 meson.build                      | 23 ++++++++++++++++++-----
 2 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/src/interfaces/libpq/meson.build b/src/interfaces/libpq/meson.build
index bc047e00d62..34cb58c2617 100644
--- a/src/interfaces/libpq/meson.build
+++ b/src/interfaces/libpq/meson.build
@@ -39,26 +39,33 @@ export_file = custom_target('libpq.exports',
 
 # port needs to be in include path due to pthread-win32.h
 libpq_inc = include_directories('.', '../../port')
+libpq_c_args = ['-DSO_MAJOR_VERSION=5']
 
+# Not using both_libraries() here as
+# 1) resource files should only be in the shared library
+# 2) we want the .pc file to include a dependency to {pgport,common}_static for
+#    libpq_st, and {pgport,common}_shlib for libpq_sh
+#
+# We could try to avoid building the source files twice, but it probably adds
+# more complexity than its worth (AIX doesn't support link_whole yet, reusing
+# object files requires also linking to the library on windows or breaks
+# precompiled headers).
 libpq_st = static_library('libpq',
   libpq_sources,
-  pic: true,
-  include_directories: [libpq_inc, postgres_inc],
-  c_args: ['-DSO_MAJOR_VERSION=5'],
-  dependencies: libpq_deps,
+  include_directories: [libpq_inc],
+  c_args: libpq_c_args,
+  dependencies: [frontend_stlib_code, libpq_deps],
   kwargs: default_lib_args,
 )
 
-# not using both_libraries here, causes problems with precompiled headers and
-# resource files with msbuild
 libpq_so = shared_library('libpq',
-  dependencies: libpq_deps,
+  libpq_sources,
   include_directories: [libpq_inc, postgres_inc],
-  c_args: ['-DSO_MAJOR_VERSION=5'],
-  link_whole: libpq_st,
+  c_args: libpq_c_args,
   version: '5.' + pg_version_major.to_string(),
   soversion: host_system != 'windows' ? '5' : '',
   darwin_versions: ['5', '5.' + pg_version_major.to_string()],
+  dependencies: [frontend_shlib_code, libpq_deps],
   link_depends: export_file,
   link_args: export_fmt.format(export_file.full_path()),
   kwargs: default_lib_args,
@@ -70,10 +77,11 @@ libpq = declare_dependency(
 )
 
 pkgconfig.generate(
-  libpq_so,
   name: 'libpq',
   description: 'PostgreSQL libpq library',
   url: pg_url,
+  libraries: libpq,
+  libraries_private: [frontend_stlib_code, libpq_deps],
 )
 
 install_headers(
diff --git a/meson.build b/meson.build
index 253994931e8..c709643fe5e 100644
--- a/meson.build
+++ b/meson.build
@@ -2619,17 +2619,29 @@ backend_common_code = declare_dependency(
 
 subdir('src/common')
 
-frontend_shlib_code = declare_dependency(
-  compile_args: ['-DFRONTEND'],
-  include_directories: [postgres_inc],
+# all shared libraries should depend on shlib_code
+shlib_code = declare_dependency(
   link_args: ldflags_sl,
-  link_with: [pgport_shlib, common_shlib],
+)
+
+# all static libraries not part of the backend should depend on this
+frontend_stlib_code = declare_dependency(
+  include_directories: [postgres_inc],
+  link_with: [common_static, pgport_static],
   sources: generated_headers,
   dependencies: [os_deps, libintl],
 )
 
+# all shared libraries not part of the backend should depend on this
+frontend_shlib_code = declare_dependency(
+  include_directories: [postgres_inc],
+  link_with: [common_shlib, pgport_shlib],
+  sources: generated_headers,
+  dependencies: [shlib_code, os_deps, libintl],
+)
+
+# Dependencies both for static and shared libpq
 libpq_deps += [
-  frontend_shlib_code,
   thread_dep,
 
   gssapi,
@@ -2642,6 +2654,7 @@ subdir('src/interfaces/libpq')
 # fe_utils depends on libpq
 subdir('src/fe_utils')
 
+# for frontend binaries
 frontend_code = declare_dependency(
   include_directories: [postgres_inc],
   link_with: [fe_utils, common_static, pgport_static],
-- 
2.37.3.542.gdd3f6c4cae

>From e5017149184a50c3131aeaec9c4b0cd2b7279c27 Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Thu, 29 Sep 2022 21:39:14 -0700
Subject: [PATCH v18 03/22] meson: ecpg: Split definition of static and shared
 libraries

Required for correct resource file generation, as the resource files should
only be added to the shared library.

This also fixes a bunch of issues in the .pc files.

Previously I tried to avoid building sources twice, once for the static and
once for the shared libraries. We could still do so, but it's not clear that
it's worth the complication.

Discussion: https://postgr.es/m/20220927011951.j3h4o7n6bhf7d...@awork3.anarazel.de
---
 src/interfaces/ecpg/compatlib/meson.build  | 39 +++++++++++++++++-----
 src/interfaces/ecpg/ecpglib/meson.build    | 33 +++++++++++++-----
 src/interfaces/ecpg/pgtypeslib/meson.build | 29 ++++++++++++----
 src/interfaces/ecpg/test/meson.build       |  2 +-
 4 files changed, 78 insertions(+), 25 deletions(-)

diff --git a/src/interfaces/ecpg/compatlib/meson.build b/src/interfaces/ecpg/compatlib/meson.build
index 5887cb92b52..b803000c708 100644
--- a/src/interfaces/ecpg/compatlib/meson.build
+++ b/src/interfaces/ecpg/compatlib/meson.build
@@ -1,11 +1,29 @@
-export_file = custom_target('libpq.exports', kwargs: gen_export_kwargs)
-
-ecpg_compat = both_libraries('libecpg_compat',
+ecpg_compat_sources = files(
   'informix.c',
-  include_directories: ['.', ecpg_inc, postgres_inc, libpq_inc],
-  c_args: ['-DSO_MAJOR_VERSION=3'],
-  dependencies: [frontend_code, thread_dep],
-  link_with: [ecpglib, ecpg_pgtypes],
+)
+ecpg_compat_so_sources = [] # for shared lib, in addition to the above
+
+ecpg_compat_inc = [include_directories('.'), ecpg_inc, libpq_inc]
+ecpg_compat_c_args = ['-DSO_MAJOR_VERSION=3']
+export_file = custom_target('libecpg_compat.exports', kwargs: gen_export_kwargs)
+
+# see src/interfaces/libpq/meson.build
+ecpg_compat_st = static_library('libecpg_compat',
+  ecpg_compat_sources,
+  include_directories: ecpg_compat_inc,
+  c_args: ecpg_compat_c_args,
+  dependencies: [frontend_stlib_code, thread_dep],
+  link_with: [ecpglib_st, ecpg_pgtypes_st],
+  kwargs: default_lib_args,
+)
+ecpg_targets += ecpg_compat_st
+
+ecpg_compat_so = shared_library('libecpg_compat',
+  ecpg_compat_sources + ecpg_compat_so_sources,
+  include_directories: ecpg_compat_inc,
+  c_args: ecpg_compat_c_args,
+  dependencies: [frontend_shlib_code, thread_dep],
+  link_with: [ecpglib_so, ecpg_pgtypes_so],
   soversion: host_system != 'windows' ? '3' : '',
   darwin_versions: ['3', '3.' + pg_version_major.to_string()],
   version: '3.' + pg_version_major.to_string(),
@@ -13,10 +31,13 @@ ecpg_compat = both_libraries('libecpg_compat',
   link_depends: export_file,
   kwargs: default_lib_args,
 )
-ecpg_targets += [ecpg_compat.get_shared_lib(), ecpg_compat.get_static_lib()]
+ecpg_targets += ecpg_compat_so
 
 pkgconfig.generate(
-  ecpg_compat.get_shared_lib(),
+  name: 'libecpg_compat',
   description: 'PostgreSQL libecpg_compat library',
   url: pg_url,
+  libraries: ecpg_compat_so,
+  libraries_private: [frontend_stlib_code, thread_dep],
+  requires_private: ['libecpg', 'libpgtypes'],
 )
diff --git a/src/interfaces/ecpg/ecpglib/meson.build b/src/interfaces/ecpg/ecpglib/meson.build
index 2da029ec8ea..6fdf019149c 100644
--- a/src/interfaces/ecpg/ecpglib/meson.build
+++ b/src/interfaces/ecpg/ecpglib/meson.build
@@ -10,15 +10,29 @@ ecpglib_sources = files(
   'sqlda.c',
   'typename.c',
 )
+ecpglib_so_sources = [] # for shared lib, in addition to the above
 
-export_file = custom_target('libpq.exports', kwargs: gen_export_kwargs)
+ecpglib_inc = [include_directories('.'), ecpg_inc]
+ecpglib_c_args = ['-DSO_MAJOR_VERSION=6']
+export_file = custom_target('libecpg.exports', kwargs: gen_export_kwargs)
 
-ecpglib = both_libraries('libecpg',
+# see src/interfaces/libpq/meson.build
+ecpglib_st = static_library('libecpg',
   ecpglib_sources,
-  include_directories: ['.', ecpg_inc, postgres_inc],
-  c_args: ['-DSO_MAJOR_VERSION=6'],
-  dependencies: [frontend_code, libpq, thread_dep],
-  link_with: [ecpg_pgtypes],
+  include_directories: ecpglib_inc,
+  c_args: ecpglib_c_args,
+  dependencies: [frontend_stlib_code, thread_dep, libpq],
+  link_with: [ecpg_pgtypes_st],
+  kwargs: default_lib_args,
+)
+ecpg_targets += ecpglib_st
+
+ecpglib_so = shared_library('libecpg',
+  ecpglib_sources + ecpglib_so_sources,
+  include_directories: ecpglib_inc,
+  c_args: ecpglib_c_args,
+  dependencies: [frontend_shlib_code, libpq, thread_dep],
+  link_with: ecpg_pgtypes_so,
   soversion: host_system != 'windows' ? '6' : '',
   darwin_versions: ['6', '6.' + pg_version_major.to_string()],
   version: '6.' + pg_version_major.to_string(),
@@ -26,12 +40,15 @@ ecpglib = both_libraries('libecpg',
   link_depends: export_file,
   kwargs: default_lib_args,
 )
-ecpg_targets += [ecpglib.get_shared_lib(), ecpglib.get_static_lib()]
+ecpg_targets += ecpglib_so
 
 pkgconfig.generate(
-  ecpglib.get_shared_lib(),
+  name: 'libecpg',
   description: 'PostgreSQL libecpg library',
   url: pg_url,
+  libraries: ecpglib_so,
+  libraries_private: [frontend_shlib_code, thread_dep],
+  requires_private: ['libpgtypes', 'libpq'],
 )
 
 subdir('po', if_found: libintl)
diff --git a/src/interfaces/ecpg/pgtypeslib/meson.build b/src/interfaces/ecpg/pgtypeslib/meson.build
index 96489d9f1d7..8e5d235810a 100644
--- a/src/interfaces/ecpg/pgtypeslib/meson.build
+++ b/src/interfaces/ecpg/pgtypeslib/meson.build
@@ -6,14 +6,27 @@ ecpg_pgtypes_sources = files(
   'numeric.c',
   'timestamp.c',
 )
+ecpg_pgtypes_so_sources = [] # for shared lib, in addition to the above
 
-export_file = custom_target('libpq.exports', kwargs: gen_export_kwargs)
+export_file = custom_target('libpgtypes.exports', kwargs: gen_export_kwargs)
+ecpg_pgtypes_inc = [include_directories('.'), ecpg_inc]
+ecpg_pgtypes_c_args = ['-DSO_MAJOR_VERSION=3']
 
-ecpg_pgtypes = both_libraries('libpgtypes',
+# see src/interfaces/libpq/meson.build
+ecpg_pgtypes_st = static_library('libpgtypes',
   ecpg_pgtypes_sources,
-  include_directories: ['.', ecpg_inc, postgres_inc],
-  c_args: ['-DSO_MAJOR_VERSION=3'],
-  dependencies: [frontend_code],
+  include_directories: ecpg_pgtypes_inc,
+  c_args: ecpg_pgtypes_c_args,
+  dependencies: frontend_stlib_code,
+  kwargs: default_lib_args,
+)
+ecpg_targets += ecpg_pgtypes_st
+
+ecpg_pgtypes_so = shared_library('libpgtypes',
+  ecpg_pgtypes_sources + ecpg_pgtypes_so_sources,
+  include_directories: ecpg_pgtypes_inc,
+  c_args: ecpg_pgtypes_c_args,
+  dependencies: frontend_shlib_code,
   version: '3.' + pg_version_major.to_string(),
   soversion: host_system != 'windows' ? '3' : '',
   darwin_versions: ['3', '3.' + pg_version_major.to_string()],
@@ -21,10 +34,12 @@ ecpg_pgtypes = both_libraries('libpgtypes',
   link_depends: export_file,
   kwargs: default_lib_args,
 )
-ecpg_targets += [ecpg_pgtypes.get_shared_lib(), ecpg_pgtypes.get_static_lib()]
+ecpg_targets += ecpg_pgtypes_so
 
 pkgconfig.generate(
-  ecpg_pgtypes.get_shared_lib(),
+  name: 'libpgtypes',
   description: 'PostgreSQL libpgtypes library',
   url: pg_url,
+  libraries: ecpg_pgtypes_so,
+  libraries_private: [frontend_stlib_code],
 )
diff --git a/src/interfaces/ecpg/test/meson.build b/src/interfaces/ecpg/test/meson.build
index f0ace641f0c..8904aa7fd90 100644
--- a/src/interfaces/ecpg/test/meson.build
+++ b/src/interfaces/ecpg/test/meson.build
@@ -22,7 +22,7 @@ testprep_targets += pg_regress_ecpg
 ecpg_test_exec_kw = {
   'dependencies': [frontend_code, libpq],
   'include_directories': [ecpg_inc],
-  'link_with': [ecpglib, ecpg_compat, ecpg_pgtypes],
+  'link_with': [ecpglib_so, ecpg_compat_so, ecpg_pgtypes_so],
   'build_by_default': false,
   'install': false,
 }
-- 
2.37.3.542.gdd3f6c4cae

>From 151755ec9b348f8ccfa2e473d4ffdd81da4fc1f2 Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Sat, 1 Oct 2022 11:54:05 -0700
Subject: [PATCH v18 04/22] meson: Add windows resource files

The generated resource files aren't exactly the same ones as the old
buildsystems generate. Previously "InternalName" and "OriginalFileName" were
mostly wrong / not set (despite being required), but that was hard to fix in
at least the make build. Additionally, the meson build falls back to a
"auto-generated" description when not set, and doesn't set it in a few cases -
unlikely that anybody looks at these descriptions in detail.

Author: Andres Freund <and...@anarazel.de>
Author: Nazir Bilal Yavuz <byavu...@gmail.com>
Reviewed-by: Peter Eisentraut <peter.eisentr...@enterprisedb.com>
---
 src/backend/jit/llvm/meson.build              |   6 +
 .../replication/libpqwalreceiver/meson.build  |   6 +
 src/backend/replication/pgoutput/meson.build  |   6 +
 src/backend/snowball/meson.build              |   6 +
 .../utils/mb/conversion_procs/meson.build     |   9 +-
 src/bin/initdb/meson.build                    |   6 +
 src/bin/pg_amcheck/meson.build                |   8 +-
 src/bin/pg_archivecleanup/meson.build         |  12 +-
 src/bin/pg_basebackup/meson.build             |  38 ++++++-
 src/bin/pg_checksums/meson.build              |  12 +-
 src/bin/pg_config/meson.build                 |  12 +-
 src/bin/pg_controldata/meson.build            |  12 +-
 src/bin/pg_ctl/meson.build                    |  12 +-
 src/bin/pg_dump/meson.build                   |  18 +++
 src/bin/pg_resetwal/meson.build               |  12 +-
 src/bin/pg_rewind/meson.build                 |   6 +
 src/bin/pg_test_fsync/meson.build             |  10 +-
 src/bin/pg_test_timing/meson.build            |  12 +-
 src/bin/pg_upgrade/meson.build                |   6 +
 src/bin/pg_verifybackup/meson.build           |   6 +
 src/bin/pg_waldump/meson.build                |   6 +
 src/bin/pgbench/meson.build                   |   6 +
 src/bin/pgevent/meson.build                   |   6 +
 src/bin/psql/meson.build                      |   6 +
 src/bin/scripts/meson.build                   |  10 +-
 src/interfaces/libpq/meson.build              |   6 +-
 src/interfaces/libpq/test/meson.build         |  25 ++++-
 src/pl/plperl/meson.build                     |   7 ++
 src/pl/plpgsql/src/meson.build                |   6 +
 src/pl/plpython/meson.build                   |   6 +
 src/pl/tcl/meson.build                        |   6 +
 contrib/adminpack/meson.build                 |  12 +-
 contrib/amcheck/meson.build                   |  17 ++-
 contrib/auth_delay/meson.build                |  12 +-
 contrib/auto_explain/meson.build              |  12 +-
 contrib/basebackup_to_shell/meson.build       |   6 +
 contrib/basic_archive/meson.build             |   6 +
 contrib/bloom/meson.build                     |   6 +
 contrib/bool_plperl/meson.build               |   6 +
 contrib/btree_gin/meson.build                 |  12 +-
 contrib/btree_gist/meson.build                |   6 +
 contrib/citext/meson.build                    |   6 +
 contrib/cube/meson.build                      |   6 +
 contrib/dblink/meson.build                    |   6 +
 contrib/dict_int/meson.build                  |  12 +-
 contrib/dict_xsyn/meson.build                 |  12 +-
 contrib/earthdistance/meson.build             |  12 +-
 contrib/file_fdw/meson.build                  |  12 +-
 contrib/fuzzystrmatch/meson.build             |  16 ++-
 contrib/hstore/meson.build                    |  24 ++--
 contrib/hstore_plperl/meson.build             |   6 +
 contrib/hstore_plpython/meson.build           |   6 +
 contrib/intarray/meson.build                  |   6 +
 contrib/isn/meson.build                       |   6 +
 contrib/jsonb_plperl/meson.build              |   6 +
 contrib/jsonb_plpython/meson.build            |   6 +
 contrib/lo/meson.build                        |   6 +
 contrib/ltree/meson.build                     |   6 +
 contrib/ltree_plpython/meson.build            |   6 +
 contrib/oid2name/meson.build                  |  12 +-
 contrib/old_snapshot/meson.build              |   6 +
 contrib/pageinspect/meson.build               |   6 +
 contrib/passwordcheck/meson.build             |   6 +
 contrib/pg_buffercache/meson.build            |  14 ++-
 contrib/pg_freespacemap/meson.build           |  14 ++-
 contrib/pg_prewarm/meson.build                |  16 ++-
 contrib/pg_stat_statements/meson.build        |  12 +-
 contrib/pg_surgery/meson.build                |  14 ++-
 contrib/pg_trgm/meson.build                   |  20 +++-
 contrib/pg_visibility/meson.build             |  14 ++-
 contrib/pg_walinspect/meson.build             |   6 +
 contrib/pgcrypto/meson.build                  |   6 +
 contrib/pgrowlocks/meson.build                |  14 ++-
 contrib/pgstattuple/meson.build               |  18 ++-
 contrib/postgres_fdw/meson.build              |   6 +
 contrib/seg/meson.build                       |   6 +
 contrib/sepgsql/meson.build                   |   6 +
 contrib/spi/meson.build                       |  48 +++++++-
 contrib/sslinfo/meson.build                   |  14 ++-
 contrib/tablefunc/meson.build                 |  14 ++-
 contrib/tcn/meson.build                       |  14 ++-
 contrib/test_decoding/meson.build             |   6 +
 contrib/tsm_system_rows/meson.build           |  14 ++-
 contrib/tsm_system_time/meson.build           |  14 ++-
 contrib/unaccent/meson.build                  |  14 ++-
 contrib/uuid-ossp/meson.build                 |  14 ++-
 contrib/vacuumlo/meson.build                  |  12 +-
 contrib/xml2/meson.build                      |  16 ++-
 src/interfaces/ecpg/compatlib/meson.build     |   6 +
 src/interfaces/ecpg/ecpglib/meson.build       |   6 +
 src/interfaces/ecpg/pgtypeslib/meson.build    |   6 +
 src/interfaces/ecpg/preproc/meson.build       |   6 +
 src/interfaces/ecpg/test/meson.build          |   5 +
 src/test/isolation/meson.build                |  13 +++
 src/test/modules/delay_execution/meson.build  |  13 ++-
 src/test/modules/dummy_index_am/meson.build   |  13 ++-
 src/test/modules/dummy_seclabel/meson.build   |  13 ++-
 src/test/modules/libpq_pipeline/meson.build   |  14 ++-
 src/test/modules/plsample/meson.build         |  13 ++-
 src/test/modules/spgist_name_ops/meson.build  |  13 ++-
 .../ssl_passphrase_callback/meson.build       |  13 ++-
 src/test/modules/test_bloomfilter/meson.build |  13 ++-
 src/test/modules/test_ddl_deparse/meson.build |  13 ++-
 .../modules/test_ginpostinglist/meson.build   |  13 ++-
 src/test/modules/test_integerset/meson.build  |  13 ++-
 src/test/modules/test_lfind/meson.build       |  13 ++-
 src/test/modules/test_oat_hooks/meson.build   |  13 ++-
 src/test/modules/test_parser/meson.build      |  13 ++-
 src/test/modules/test_predtest/meson.build    |  13 ++-
 src/test/modules/test_rbtree/meson.build      |  13 ++-
 src/test/modules/test_regex/meson.build       |  13 ++-
 src/test/modules/test_rls_hooks/meson.build   |  13 ++-
 src/test/modules/test_shm_mq/meson.build      |  19 +++-
 src/test/modules/worker_spi/meson.build       |  15 ++-
 src/test/regress/meson.build                  |   6 +
 meson.build                                   |  59 ++++++++++
 src/timezone/meson.build                      |   6 +
 src/tools/rcgen                               | 105 ++++++++++++++++++
 118 files changed, 1292 insertions(+), 131 deletions(-)
 create mode 100755 src/tools/rcgen

diff --git a/src/backend/jit/llvm/meson.build b/src/backend/jit/llvm/meson.build
index 6ae7aaad015..25c5618e8a3 100644
--- a/src/backend/jit/llvm/meson.build
+++ b/src/backend/jit/llvm/meson.build
@@ -20,6 +20,12 @@ llvmjit_sources += files(
   'llvmjit_expr.c',
 )
 
+if host_system == 'windows'
+  llvmjit_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'llvmjit',
+    '--FILEDESC', 'llvmjit - JIT using LLVM',])
+endif
+
 llvmjit = shared_module('llvmjit',
   llvmjit_sources,
   kwargs: pg_mod_args + {
diff --git a/src/backend/replication/libpqwalreceiver/meson.build b/src/backend/replication/libpqwalreceiver/meson.build
index 3fc786c80a0..4c653a05d36 100644
--- a/src/backend/replication/libpqwalreceiver/meson.build
+++ b/src/backend/replication/libpqwalreceiver/meson.build
@@ -2,6 +2,12 @@ libpqwalreceiver_sources = files(
   'libpqwalreceiver.c',
 )
 
+if host_system == 'windows'
+  libpqwalreceiver_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pqwalreceiver',
+    '--FILEDESC', 'libpqwalreceiver - receive WAL during streaming replication',])
+endif
+
 libpqwalreceiver = shared_module('pqwalreceiver',
   libpqwalreceiver_sources,
   kwargs: pg_mod_args + {
diff --git a/src/backend/replication/pgoutput/meson.build b/src/backend/replication/pgoutput/meson.build
index ab956361a62..5df27d7b764 100644
--- a/src/backend/replication/pgoutput/meson.build
+++ b/src/backend/replication/pgoutput/meson.build
@@ -2,6 +2,12 @@ pgoutput_sources = files(
   'pgoutput.c',
 )
 
+if host_system == 'windows'
+  pgoutput_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pgoutput',
+    '--FILEDESC', 'pgoutput - standard logical replication output plugin',])
+endif
+
 pgoutput = shared_module('pgoutput',
   pgoutput_sources,
   kwargs: pg_mod_args,
diff --git a/src/backend/snowball/meson.build b/src/backend/snowball/meson.build
index 8c6f685cb32..974401d187e 100644
--- a/src/backend/snowball/meson.build
+++ b/src/backend/snowball/meson.build
@@ -58,6 +58,12 @@ dict_snowball_sources += files(
 # see comment in src/include/snowball/header.h
 stemmer_inc = include_directories('../../include/snowball')
 
+if host_system == 'windows'
+  dict_snowball_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'dict_snowball',
+    '--FILEDESC', 'snowball - natural language stemmers',])
+endif
+
 dict_snowball = shared_module('dict_snowball',
   dict_snowball_sources,
   kwargs: pg_mod_args + {
diff --git a/src/backend/utils/mb/conversion_procs/meson.build b/src/backend/utils/mb/conversion_procs/meson.build
index 1bc971d1945..1c18f2ac85a 100644
--- a/src/backend/utils/mb/conversion_procs/meson.build
+++ b/src/backend/utils/mb/conversion_procs/meson.build
@@ -29,8 +29,15 @@ encodings = {
 }
 
 foreach encoding, sources : encodings
+  source_files = files(sources)
+
+  if host_system == 'windows'
+    source_files += rc_lib_gen.process(win32ver_rc, extra_args: [
+      '--NAME', encoding])
+  endif
+
   backend_targets += shared_module(encoding,
-    sources,
+    source_files,
     kwargs: pg_mod_args,
   )
 endforeach
diff --git a/src/bin/initdb/meson.build b/src/bin/initdb/meson.build
index 9f213274d2f..6ced9a31b80 100644
--- a/src/bin/initdb/meson.build
+++ b/src/bin/initdb/meson.build
@@ -7,6 +7,12 @@ initdb_sources += timezone_localtime_source
 
 #fixme: reimplement libpq_pgport logic
 
+if host_system == 'windows'
+  initdb_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'initdb',
+    '--FILEDESC', 'initdb - initialize a new database cluster',])
+endif
+
 initdb = executable('initdb',
   initdb_sources,
   include_directories: [timezone_inc],
diff --git a/src/bin/pg_amcheck/meson.build b/src/bin/pg_amcheck/meson.build
index 8e197eba5f3..25f5e7a0948 100644
--- a/src/bin/pg_amcheck/meson.build
+++ b/src/bin/pg_amcheck/meson.build
@@ -1,7 +1,13 @@
 pg_amcheck_sources = files(
-  'pg_amcheck.c'
+  'pg_amcheck.c',
 )
 
+if host_system == 'windows'
+  pg_amcheck_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_amcheck',
+    '--FILEDESC', 'pg_amcheck - detect corruption within database relations',])
+endif
+
 pg_amcheck = executable('pg_amcheck',
   pg_amcheck_sources,
   dependencies: [frontend_code, libpq],
diff --git a/src/bin/pg_archivecleanup/meson.build b/src/bin/pg_archivecleanup/meson.build
index 87a0d980c4f..aaa2e76977f 100644
--- a/src/bin/pg_archivecleanup/meson.build
+++ b/src/bin/pg_archivecleanup/meson.build
@@ -1,5 +1,15 @@
+pg_archivecleanup_sources = files(
+  'pg_archivecleanup.c',
+)
+
+if host_system == 'windows'
+  pg_archivecleanup_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_archivecleanup',
+    '--FILEDESC', 'pg_archivecleanup - cleans archive when used with streaming replication',])
+endif
+
 pg_archivecleanup = executable('pg_archivecleanup',
-  ['pg_archivecleanup.c'],
+  pg_archivecleanup_sources,
   dependencies: [frontend_code],
   kwargs: default_bin_args,
 )
diff --git a/src/bin/pg_basebackup/meson.build b/src/bin/pg_basebackup/meson.build
index d26fed9cd8a..2c934e0c26e 100644
--- a/src/bin/pg_basebackup/meson.build
+++ b/src/bin/pg_basebackup/meson.build
@@ -17,24 +17,56 @@ pg_basebackup_common = static_library('libpg_basebackup_common',
   kwargs: internal_lib_args,
 )
 
-pg_basebackup = executable('pg_basebackup',
+pg_basebackup_sources = files(
   'pg_basebackup.c',
+)
+
+if host_system == 'windows'
+  pg_basebackup_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_basebackup',
+    '--FILEDESC', 'pg_basebackup - streaming WAL and backup receivers',])
+endif
+
+pg_basebackup = executable('pg_basebackup',
+  pg_basebackup_sources,
   link_with: [pg_basebackup_common],
   dependencies: pg_basebackup_deps,
   kwargs: default_bin_args,
 )
 bin_targets += pg_basebackup
 
-pg_receivewal = executable('pg_receivewal',
+
+pg_receivewal_sources = files(
   'pg_receivewal.c',
+)
+
+if host_system == 'windows'
+  pg_receivewal_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_receivewal',
+    '--FILEDESC', 'pg_receivewal - streaming WAL and backup receivers',])
+endif
+
+pg_receivewal = executable('pg_receivewal',
+  pg_receivewal_sources,
   link_with: [pg_basebackup_common],
   dependencies: pg_basebackup_deps,
   kwargs: default_bin_args,
 )
 bin_targets += pg_receivewal
 
-pg_recvlogical = executable('pg_recvlogical',
+
+pg_recvlogical_sources = files(
   'pg_recvlogical.c',
+)
+
+if host_system == 'windows'
+  pg_recvlogical_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_recvlogical',
+    '--FILEDESC', 'pg_recvlogical - streaming WAL and backup receivers',])
+endif
+
+pg_recvlogical = executable('pg_recvlogical',
+  pg_recvlogical_sources,
   link_with: [pg_basebackup_common],
   dependencies: pg_basebackup_deps,
   kwargs: default_bin_args,
diff --git a/src/bin/pg_checksums/meson.build b/src/bin/pg_checksums/meson.build
index ee1f367bac3..d07ebc999b3 100644
--- a/src/bin/pg_checksums/meson.build
+++ b/src/bin/pg_checksums/meson.build
@@ -1,5 +1,15 @@
+pg_checksums_sources = files(
+  'pg_checksums.c',
+)
+
+if host_system == 'windows'
+  pg_checksums_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_checksums',
+    '--FILEDESC', 'pg_checksums - verify data checksums in an offline cluster',])
+endif
+
 pg_checksums = executable('pg_checksums',
-  ['pg_checksums.c'],
+  pg_checksums_sources,
   include_directories: [timezone_inc],
   dependencies: [frontend_code],
   kwargs: default_bin_args,
diff --git a/src/bin/pg_config/meson.build b/src/bin/pg_config/meson.build
index 0ecbf2f9d28..4be2fdc84ae 100644
--- a/src/bin/pg_config/meson.build
+++ b/src/bin/pg_config/meson.build
@@ -1,5 +1,15 @@
+pg_config_sources = files(
+  'pg_config.c',
+)
+
+if host_system == 'windows'
+  pg_config_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_config',
+    '--FILEDESC', 'pg_config - report configuration information',])
+endif
+
 pg_config = executable('pg_config',
-  ['pg_config.c'],
+  pg_config_sources,
   dependencies: [frontend_code],
   kwargs: default_bin_args,
 )
diff --git a/src/bin/pg_controldata/meson.build b/src/bin/pg_controldata/meson.build
index 557e672beb7..7fc239dbe65 100644
--- a/src/bin/pg_controldata/meson.build
+++ b/src/bin/pg_controldata/meson.build
@@ -1,5 +1,15 @@
+pg_controldata_sources = files(
+  'pg_controldata.c',
+)
+
+if host_system == 'windows'
+  pg_controldata_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_controldata',
+    '--FILEDESC', 'pg_controldata - reads the data from pg_control',])
+endif
+
 pg_controldata = executable('pg_controldata',
-  ['pg_controldata.c'],
+  pg_controldata_sources,
   dependencies: [frontend_code],
   kwargs: default_bin_args,
 )
diff --git a/src/bin/pg_ctl/meson.build b/src/bin/pg_ctl/meson.build
index 6812e73e329..96f962fa762 100644
--- a/src/bin/pg_ctl/meson.build
+++ b/src/bin/pg_ctl/meson.build
@@ -1,5 +1,15 @@
+pg_ctl_sources = files(
+  'pg_ctl.c',
+)
+
+if host_system == 'windows'
+  pg_ctl_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_ctl',
+    '--FILEDESC', 'pg_ctl - starts/stops/restarts the PostgreSQL server',])
+endif
+
 pg_ctl = executable('pg_ctl',
-  ['pg_ctl.c'],
+  pg_ctl_sources,
   dependencies: [frontend_code, libpq],
   kwargs: default_bin_args,
 )
diff --git a/src/bin/pg_dump/meson.build b/src/bin/pg_dump/meson.build
index 785ec094dbd..3527a25c288 100644
--- a/src/bin/pg_dump/meson.build
+++ b/src/bin/pg_dump/meson.build
@@ -24,6 +24,12 @@ pg_dump_sources = files(
   'pg_dump_sort.c',
 )
 
+if host_system == 'windows'
+  pg_dump_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_dump',
+    '--FILEDESC', 'pg_dump - backup one PostgreSQL database',])
+endif
+
 pg_dump = executable('pg_dump',
   pg_dump_sources,
   link_with: [pg_dump_common],
@@ -37,6 +43,12 @@ pg_dumpall_sources = files(
   'pg_dumpall.c',
 )
 
+if host_system == 'windows'
+  pg_dumpall_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_dumpall',
+    '--FILEDESC', 'pg_dumpall - backup PostgreSQL databases'])
+endif
+
 pg_dumpall = executable('pg_dumpall',
   pg_dumpall_sources,
   link_with: [pg_dump_common],
@@ -50,6 +62,12 @@ pg_restore_sources = files(
   'pg_restore.c',
 )
 
+if host_system == 'windows'
+  pg_restore_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_restore',
+    '--FILEDESC', 'pg_restore - restore PostgreSQL databases'])
+endif
+
 pg_restore = executable('pg_restore',
   pg_restore_sources,
   link_with: [pg_dump_common],
diff --git a/src/bin/pg_resetwal/meson.build b/src/bin/pg_resetwal/meson.build
index 7c5de134ac0..d503db97b71 100644
--- a/src/bin/pg_resetwal/meson.build
+++ b/src/bin/pg_resetwal/meson.build
@@ -1,5 +1,15 @@
+pg_resetwal_sources = files(
+  'pg_resetwal.c',
+)
+
+if host_system == 'windows'
+  pg_resetwal_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_resetwal',
+    '--FILEDESC', 'pg_resetwal - reset PostgreSQL WAL log'])
+endif
+
 pg_resetwal = executable('pg_resetwal',
-  files('pg_resetwal.c'),
+  pg_resetwal_sources,
   dependencies: [frontend_code],
   kwargs: default_bin_args,
 )
diff --git a/src/bin/pg_rewind/meson.build b/src/bin/pg_rewind/meson.build
index d8ec9e482d5..6cd970909a2 100644
--- a/src/bin/pg_rewind/meson.build
+++ b/src/bin/pg_rewind/meson.build
@@ -11,6 +11,12 @@ pg_rewind_sources = files(
 
 pg_rewind_sources += xlogreader_sources
 
+if host_system == 'windows'
+  pg_rewind_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_rewind',
+    '--FILEDESC', 'pg_rewind - synchronize a data directory with another one forked from'])
+endif
+
 pg_rewind = executable('pg_rewind',
   pg_rewind_sources,
   dependencies: [frontend_code, libpq, lz4, zstd],
diff --git a/src/bin/pg_test_fsync/meson.build b/src/bin/pg_test_fsync/meson.build
index 2c01831e11f..31d288ba6da 100644
--- a/src/bin/pg_test_fsync/meson.build
+++ b/src/bin/pg_test_fsync/meson.build
@@ -1,4 +1,12 @@
-test_fsync_sources = files('pg_test_fsync.c')
+test_fsync_sources = files(
+  'pg_test_fsync.c',
+)
+
+if host_system == 'windows'
+  test_fsync_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_test_fsync',
+    '--FILEDESC', 'pg_test_fsync - test various disk sync methods'])
+endif
 
 pg_test_fsync = executable('pg_test_fsync',
   test_fsync_sources,
diff --git a/src/bin/pg_test_timing/meson.build b/src/bin/pg_test_timing/meson.build
index 0a3068f1657..0aed03ea32f 100644
--- a/src/bin/pg_test_timing/meson.build
+++ b/src/bin/pg_test_timing/meson.build
@@ -1,5 +1,15 @@
+pg_test_timing_sources = files(
+  'pg_test_timing.c'
+)
+
+if host_system == 'windows'
+  pg_test_timing_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_test_timing',
+    '--FILEDESC', 'pg_test_timing - test timing overhead'])
+endif
+
 pg_test_timing = executable('pg_test_timing',
-  ['pg_test_timing.c'],
+  pg_test_timing_sources,
   dependencies: [frontend_code],
   kwargs: default_bin_args,
 )
diff --git a/src/bin/pg_upgrade/meson.build b/src/bin/pg_upgrade/meson.build
index 02f030e0ccf..a7b927a45c7 100644
--- a/src/bin/pg_upgrade/meson.build
+++ b/src/bin/pg_upgrade/meson.build
@@ -16,6 +16,12 @@ pg_upgrade_sources = files(
   'version.c',
 )
 
+if host_system == 'windows'
+  pg_upgrade_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_upgrade',
+    '--FILEDESC', 'pg_upgrade - an in-place binary upgrade utility'])
+endif
+
 pg_upgrade = executable('pg_upgrade',
   pg_upgrade_sources,
   dependencies: [frontend_code, libpq],
diff --git a/src/bin/pg_verifybackup/meson.build b/src/bin/pg_verifybackup/meson.build
index 4c3b2bb5f97..b934a408443 100644
--- a/src/bin/pg_verifybackup/meson.build
+++ b/src/bin/pg_verifybackup/meson.build
@@ -3,6 +3,12 @@ pg_verifybackup_sources = files(
   'pg_verifybackup.c'
 )
 
+if host_system == 'windows'
+  pg_verifybackup_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_verifybackup',
+    '--FILEDESC', 'pg_verifybackup - verify a backup against using a backup manifest'])
+endif
+
 pg_verifybackup = executable('pg_verifybackup',
   pg_verifybackup_sources,
   dependencies: [frontend_code, libpq],
diff --git a/src/bin/pg_waldump/meson.build b/src/bin/pg_waldump/meson.build
index 95872652ffd..9605976870d 100644
--- a/src/bin/pg_waldump/meson.build
+++ b/src/bin/pg_waldump/meson.build
@@ -8,6 +8,12 @@ pg_waldump_sources += rmgr_desc_sources
 pg_waldump_sources += xlogreader_sources
 pg_waldump_sources += files('../../backend/access/transam/xlogstats.c')
 
+if host_system == 'windows'
+  pg_waldump_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_waldump',
+    '--FILEDESC', 'pg_waldump - decode and display WA'])
+endif
+
 pg_waldump = executable('pg_waldump',
   pg_waldump_sources,
   dependencies: [frontend_code, lz4, zstd],
diff --git a/src/bin/pgbench/meson.build b/src/bin/pgbench/meson.build
index 6564e54029c..a32eb51fe07 100644
--- a/src/bin/pgbench/meson.build
+++ b/src/bin/pgbench/meson.build
@@ -17,6 +17,12 @@ exprparse = custom_target('exprparse',
 generated_sources += exprparse.to_list()
 pgbench_sources += exprparse
 
+if host_system == 'windows'
+  pgbench_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pgbench',
+    '--FILEDESC', 'pgbench - a simple program for running benchmark tests'])
+endif
+
 pgbench = executable('pgbench',
   pgbench_sources,
   dependencies: [frontend_code, libpq, thread_dep],
diff --git a/src/bin/pgevent/meson.build b/src/bin/pgevent/meson.build
index 7a468879fd2..2e9aea4b0e1 100644
--- a/src/bin/pgevent/meson.build
+++ b/src/bin/pgevent/meson.build
@@ -6,6 +6,12 @@ pgevent_sources = files(
   'pgevent.c',
 )
 
+pgevent_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+  '--NAME', 'pgevent',
+  '--FILEDESC', 'Eventlog message formatter',])
+
+pgevent_sources += windows.compile_resources('pgmsgevent.rc')
+
 # FIXME: copied from Mkvcbuild.pm, but I don't think that's the right approach
 pgevent_link_args = []
 if cc.get_id() == 'msvc'
diff --git a/src/bin/psql/meson.build b/src/bin/psql/meson.build
index 410788e4767..1264fc19fbd 100644
--- a/src/bin/psql/meson.build
+++ b/src/bin/psql/meson.build
@@ -36,6 +36,12 @@ sql_help = custom_target('psql_help',
 generated_sources += sql_help.to_list()
 psql_sources += sql_help
 
+if host_system == 'windows'
+  psql_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'psql',
+    '--FILEDESC', 'psql - the PostgreSQL interactive terminal',])
+endif
+
 psql = executable('psql',
   psql_sources,
   include_directories: include_directories('.'),
diff --git a/src/bin/scripts/meson.build b/src/bin/scripts/meson.build
index eaf250c7f73..837562c24e5 100644
--- a/src/bin/scripts/meson.build
+++ b/src/bin/scripts/meson.build
@@ -16,8 +16,16 @@ binaries = [
 ]
 
 foreach binary : binaries
+  binary_sources = files('@0@.c'.format(binary))
+
+  if host_system == 'windows'
+    binary_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+      '--NAME', binary,
+      '--FILEDESC', '@0@ - PostgreSQL utility'.format(binary),])
+  endif
+
   binary = executable(binary,
-    files(binary + '.c'),
+    binary_sources,
     link_with: [scripts_common],
     dependencies: [frontend_code, libpq],
     kwargs: default_bin_args,
diff --git a/src/interfaces/libpq/meson.build b/src/interfaces/libpq/meson.build
index 34cb58c2617..533b2e6f773 100644
--- a/src/interfaces/libpq/meson.build
+++ b/src/interfaces/libpq/meson.build
@@ -16,9 +16,13 @@ libpq_sources = files(
   'libpq-events.c',
   'pqexpbuffer.c',
 )
+libpq_so_sources = [] # for shared lib, in addition to the above
 
 if host_system == 'windows'
   libpq_sources += files('pthread-win32.c', 'win32.c')
+  libpq_so_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'libpq',
+    '--FILEDESC', 'PostgreSQL Access Library',])
 endif
 
 if ssl.found()
@@ -59,7 +63,7 @@ libpq_st = static_library('libpq',
 )
 
 libpq_so = shared_library('libpq',
-  libpq_sources,
+  libpq_sources + libpq_so_sources,
   include_directories: [libpq_inc, postgres_inc],
   c_args: libpq_c_args,
   version: '5.' + pg_version_major.to_string(),
diff --git a/src/interfaces/libpq/test/meson.build b/src/interfaces/libpq/test/meson.build
index 16f94c1ed8b..017f729d435 100644
--- a/src/interfaces/libpq/test/meson.build
+++ b/src/interfaces/libpq/test/meson.build
@@ -1,13 +1,34 @@
+libpq_uri_regress_sources = files(
+  'libpq_uri_regress.c',
+)
+
+if host_system == 'windows'
+  libpq_uri_regress_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'libpq_uri_regress',
+    '--FILEDESC', 'libpq test program',])
+endif
+
 executable('libpq_uri_regress',
-  files('libpq_uri_regress.c'),
+  libpq_uri_regress_sources,
   dependencies: [frontend_code, libpq],
   kwargs: default_bin_args + {
     'install': false,
   }
 )
 
+
+libpq_testclient_sources = files(
+  'libpq_testclient.c',
+)
+
+if host_system == 'windows'
+  libpq_testclient_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'libpq_testclient',
+    '--FILEDESC', 'libpq test program',])
+endif
+
 executable('libpq_testclient',
-  files('libpq_testclient.c'),
+  libpq_testclient_sources,
   dependencies: [frontend_code, libpq],
   kwargs: default_bin_args + {
     'install': false,
diff --git a/src/pl/plperl/meson.build b/src/pl/plperl/meson.build
index 73b733dd50b..535660085dd 100644
--- a/src/pl/plperl/meson.build
+++ b/src/pl/plperl/meson.build
@@ -36,6 +36,13 @@ foreach n : ['SPI', 'Util']
 endforeach
 
 plperl_inc = include_directories('.')
+
+if host_system == 'windows'
+  plperl_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'plperl',
+    '--FILEDESC', 'PL/Perl - procedural language',])
+endif
+
 plperl = shared_module('plperl',
   plperl_sources,
   include_directories: [plperl_inc, postgres_inc],
diff --git a/src/pl/plpgsql/src/meson.build b/src/pl/plpgsql/src/meson.build
index dd499fdd151..c46c0a1da2a 100644
--- a/src/pl/plpgsql/src/meson.build
+++ b/src/pl/plpgsql/src/meson.build
@@ -40,6 +40,12 @@ pl_unreserved = custom_target('pl_unreserved_kwlist',
 generated_sources += pl_unreserved
 plpgsql_sources += pl_unreserved
 
+if host_system == 'windows'
+  plpgsql_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'plpgsql',
+    '--FILEDESC', 'PL/pgSQL - procedural language',])
+endif
+
 plpgsql = shared_module('plpgsql',
   plpgsql_sources,
   include_directories: include_directories('.'),
diff --git a/src/pl/plpython/meson.build b/src/pl/plpython/meson.build
index 366b3b171ac..40888386b5f 100644
--- a/src/pl/plpython/meson.build
+++ b/src/pl/plpython/meson.build
@@ -28,6 +28,12 @@ plpython_sources += custom_target('spiexceptions.h',
 # FIXME: need to duplicate import library ugliness?
 plpython_inc = include_directories('.')
 
+if host_system == 'windows'
+  plpython_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'plpython3',
+    '--FILEDESC', 'PL/Python - procedural language',])
+endif
+
 plpython = shared_module('plpython3',
   plpython_sources,
   include_directories: [plpython_inc, postgres_inc],
diff --git a/src/pl/tcl/meson.build b/src/pl/tcl/meson.build
index 9b6addd7fd5..f09bb14c950 100644
--- a/src/pl/tcl/meson.build
+++ b/src/pl/tcl/meson.build
@@ -14,6 +14,12 @@ pltcl_sources += custom_target('pltclerrcodes.h',
   command: [perl, gen_pltclerrcodes, '@INPUT@']
 )
 
+if host_system == 'windows'
+  pltcl_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pltcl',
+    '--FILEDESC', 'PL/Tcl - procedural language',])
+endif
+
 pltcl = shared_module('pltcl',
   pltcl_sources,
   include_directories: [include_directories('.'), postgres_inc],
diff --git a/contrib/adminpack/meson.build b/contrib/adminpack/meson.build
index fc2368d02cf..7efec0efbc0 100644
--- a/contrib/adminpack/meson.build
+++ b/contrib/adminpack/meson.build
@@ -1,5 +1,15 @@
+adminpack_sources = files(
+  'adminpack.c',
+)
+
+if host_system == 'windows'
+  adminpack_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'adminpack',
+    '--FILEDESC', 'adminpack - support functions for pgAdmin',])
+endif
+
 adminpack = shared_module('adminpack',
-  ['adminpack.c'],
+  adminpack_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += adminpack
diff --git a/contrib/amcheck/meson.build b/contrib/amcheck/meson.build
index 1db3d20349e..fa807b72d98 100644
--- a/contrib/amcheck/meson.build
+++ b/contrib/amcheck/meson.build
@@ -1,7 +1,16 @@
-amcheck = shared_module('amcheck', [
-    'verify_heapam.c',
-    'verify_nbtree.c',
-  ],
+amcheck_sources = files(
+  'verify_heapam.c',
+  'verify_nbtree.c',
+)
+
+if host_system == 'windows'
+  amcheck_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'amcheck',
+    '--FILEDESC', 'amcheck - function for verifying relation integrity',])
+endif
+
+amcheck = shared_module('amcheck',
+  amcheck_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += amcheck
diff --git a/contrib/auth_delay/meson.build b/contrib/auth_delay/meson.build
index d2e01968f54..c4ffb0663bc 100644
--- a/contrib/auth_delay/meson.build
+++ b/contrib/auth_delay/meson.build
@@ -1,5 +1,15 @@
+auth_delay_sources = files(
+  'auth_delay.c',
+)
+
+if host_system == 'windows'
+  auth_delay_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'auth_delay',
+    '--FILEDESC', 'auth_delay - delay authentication failure reports',])
+endif
+
 autoinc = shared_module('auth_delay',
-  ['auth_delay.c'],
+  auth_delay_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += autoinc
diff --git a/contrib/auto_explain/meson.build b/contrib/auto_explain/meson.build
index 249a8376faa..76f86617850 100644
--- a/contrib/auto_explain/meson.build
+++ b/contrib/auto_explain/meson.build
@@ -1,5 +1,15 @@
+auto_explain_sources = files(
+  'auto_explain.c',
+)
+
+if host_system == 'windows'
+  auto_explain_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'auto_explain',
+    '--FILEDESC', 'auto_explain - logging facility for execution plans',])
+endif
+
 auto_explain = shared_module('auto_explain',
-  files('auto_explain.c'),
+  auto_explain_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += auto_explain
diff --git a/contrib/basebackup_to_shell/meson.build b/contrib/basebackup_to_shell/meson.build
index 9f0517f1701..3a389de9175 100644
--- a/contrib/basebackup_to_shell/meson.build
+++ b/contrib/basebackup_to_shell/meson.build
@@ -2,6 +2,12 @@ basebackup_to_shell_sources = files(
   'basebackup_to_shell.c',
 )
 
+if host_system == 'windows'
+  basebackup_to_shell_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'basebackup_to_shell',
+    '--FILEDESC', 'basebackup_to_shell - target basebackup to shell command',])
+endif
+
 basebackup_to_shell = shared_module('basebackup_to_shell',
   basebackup_to_shell_sources,
   kwargs: contrib_mod_args,
diff --git a/contrib/basic_archive/meson.build b/contrib/basic_archive/meson.build
index b67cbef60bd..c30dcfa5d41 100644
--- a/contrib/basic_archive/meson.build
+++ b/contrib/basic_archive/meson.build
@@ -2,6 +2,12 @@ basic_archive_sources = files(
   'basic_archive.c',
 )
 
+if host_system == 'windows'
+  basic_archive_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'basic_archive',
+    '--FILEDESC', 'basic_archive - basic archive module',])
+endif
+
 basic_archive = shared_module('basic_archive',
   basic_archive_sources,
   kwargs: contrib_mod_args,
diff --git a/contrib/bloom/meson.build b/contrib/bloom/meson.build
index 1fe7632bdbe..16f3b83e4d2 100644
--- a/contrib/bloom/meson.build
+++ b/contrib/bloom/meson.build
@@ -7,6 +7,12 @@ bloom_sources = files(
   'blvalidate.c',
 )
 
+if host_system == 'windows'
+  bloom_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'bloom',
+    '--FILEDESC', 'bloom access method - signature file based index',])
+endif
+
 bloom = shared_module('bloom',
   bloom_sources,
   kwargs: contrib_mod_args,
diff --git a/contrib/bool_plperl/meson.build b/contrib/bool_plperl/meson.build
index c20b667d75f..a68daab0dcd 100644
--- a/contrib/bool_plperl/meson.build
+++ b/contrib/bool_plperl/meson.build
@@ -6,6 +6,12 @@ bool_plperl_sources = files(
   'bool_plperl.c',
 )
 
+if host_system == 'windows'
+  bool_plperl_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'bool_plperl',
+    '--FILEDESC', 'bool_plperl - bool transform for plperl',])
+endif
+
 bool_plperl = shared_module('bool_plperl',
   bool_plperl_sources,
   include_directories: [plperl_inc, include_directories('.')],
diff --git a/contrib/btree_gin/meson.build b/contrib/btree_gin/meson.build
index 15d6d31a6ee..fd4c76767a7 100644
--- a/contrib/btree_gin/meson.build
+++ b/contrib/btree_gin/meson.build
@@ -1,5 +1,15 @@
+btree_gin_sources = files(
+  'btree_gin.c',
+)
+
+if host_system == 'windows'
+  btree_gin_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'btree_gin',
+    '--FILEDESC', 'btree_gin - B-tree equivalent GIN operator classes',])
+endif
+
 btree_gin = shared_module('btree_gin',
-  files('btree_gin.c'),
+  btree_gin_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += btree_gin
diff --git a/contrib/btree_gist/meson.build b/contrib/btree_gist/meson.build
index c0a8d238540..e98c91dacc8 100644
--- a/contrib/btree_gist/meson.build
+++ b/contrib/btree_gist/meson.build
@@ -25,6 +25,12 @@ btree_gist_sources = files(
   'btree_uuid.c',
 )
 
+if host_system == 'windows'
+  btree_gist_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'btree_gist',
+    '--FILEDESC', 'btree_gist - B-tree equivalent GiST operator classes',])
+endif
+
 btree_gist = shared_module('btree_gist',
   btree_gist_sources,
   kwargs: contrib_mod_args,
diff --git a/contrib/citext/meson.build b/contrib/citext/meson.build
index ca60eded80b..26a101a19bd 100644
--- a/contrib/citext/meson.build
+++ b/contrib/citext/meson.build
@@ -2,6 +2,12 @@ citext_sources = files(
   'citext.c',
 )
 
+if host_system == 'windows'
+  citext_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'citext',
+    '--FILEDESC', 'citext - case-insensitive character string data type',])
+endif
+
 citext = shared_module('citext',
   citext_sources,
   kwargs: contrib_mod_args,
diff --git a/contrib/cube/meson.build b/contrib/cube/meson.build
index 72342b0c82c..041acf95a90 100644
--- a/contrib/cube/meson.build
+++ b/contrib/cube/meson.build
@@ -17,6 +17,12 @@ cube_parse = custom_target('cubeparse',
 generated_sources += cube_parse.to_list()
 cube_sources += cube_parse
 
+if host_system == 'windows'
+  cube_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'cube',
+    '--FILEDESC', 'cube - multidimensional cube data type',])
+endif
+
 cube = shared_module('cube',
   cube_sources,
   include_directories: include_directories('.'),
diff --git a/contrib/dblink/meson.build b/contrib/dblink/meson.build
index d35f7b5d49e..66eeb03b736 100644
--- a/contrib/dblink/meson.build
+++ b/contrib/dblink/meson.build
@@ -2,6 +2,12 @@ dblink_sources = files(
   'dblink.c',
 )
 
+if host_system == 'windows'
+  dblink_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'dblink',
+    '--FILEDESC', 'dblink - connect to other PostgreSQL databases',])
+endif
+
 dblink = shared_module('dblink',
   dblink_sources,
   kwargs: contrib_mod_args + {
diff --git a/contrib/dict_int/meson.build b/contrib/dict_int/meson.build
index f00e8085619..6fff921adda 100644
--- a/contrib/dict_int/meson.build
+++ b/contrib/dict_int/meson.build
@@ -1,5 +1,15 @@
+dict_int_sources = files(
+  'dict_int.c',
+)
+
+if host_system == 'windows'
+  dict_int_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'dict_int',
+    '--FILEDESC', 'dict_int - add-on dictionary template for full-text search',])
+endif
+
 dict_int = shared_module('dict_int',
-  files('dict_int.c'),
+  dict_int_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += dict_int
diff --git a/contrib/dict_xsyn/meson.build b/contrib/dict_xsyn/meson.build
index be53f55bb79..fabd505a7df 100644
--- a/contrib/dict_xsyn/meson.build
+++ b/contrib/dict_xsyn/meson.build
@@ -1,5 +1,15 @@
+dict_xsyn_sources = files(
+  'dict_xsyn.c',
+)
+
+if host_system == 'windows'
+  dict_xsyn_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'dict_xsyn',
+    '--FILEDESC', 'dict_xsyn - add-on dictionary template for full-text search',])
+endif
+
 dict_xsyn = shared_module('dict_xsyn',
-  files('dict_xsyn.c'),
+  dict_xsyn_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += dict_xsyn
diff --git a/contrib/earthdistance/meson.build b/contrib/earthdistance/meson.build
index 807f5cb7de3..78dc29c3da3 100644
--- a/contrib/earthdistance/meson.build
+++ b/contrib/earthdistance/meson.build
@@ -1,5 +1,15 @@
+earthdistance_sources = files(
+  'earthdistance.c',
+)
+
+if host_system == 'windows'
+  earthdistance_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'earthdistance',
+    '--FILEDESC', 'earthdistance - calculate distances on the surface of the Earth',])
+endif
+
 earthdistance = shared_module('earthdistance',
-  files('earthdistance.c'),
+  earthdistance_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += earthdistance
diff --git a/contrib/file_fdw/meson.build b/contrib/file_fdw/meson.build
index f13efb6e38e..c4071faa669 100644
--- a/contrib/file_fdw/meson.build
+++ b/contrib/file_fdw/meson.build
@@ -1,5 +1,15 @@
+file_fdw_sources = files(
+  'file_fdw.c',
+)
+
+if host_system == 'windows'
+  file_fdw_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'file_fdw',
+    '--FILEDESC', 'file_fdw - foreign data wrapper for files',])
+endif
+
 file_fdw = shared_module('file_fdw',
-  files('file_fdw.c'),
+  file_fdw_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += file_fdw
diff --git a/contrib/fuzzystrmatch/meson.build b/contrib/fuzzystrmatch/meson.build
index ec278a6211e..e6d06149cec 100644
--- a/contrib/fuzzystrmatch/meson.build
+++ b/contrib/fuzzystrmatch/meson.build
@@ -1,8 +1,16 @@
+fuzzystrmatch_sources = files(
+  'fuzzystrmatch.c',
+  'dmetaphone.c',
+)
+
+if host_system == 'windows'
+  fuzzystrmatch_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'fuzzystrmatch',
+    '--FILEDESC', 'fuzzystrmatch - similarities and distance between strings',])
+endif
+
 fuzzystrmatch = shared_module('fuzzystrmatch',
-  files(
-    'fuzzystrmatch.c',
-    'dmetaphone.c'
-  ),
+  fuzzystrmatch_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += fuzzystrmatch
diff --git a/contrib/hstore/meson.build b/contrib/hstore/meson.build
index 07c59f40a97..2bb26bb772b 100644
--- a/contrib/hstore/meson.build
+++ b/contrib/hstore/meson.build
@@ -1,15 +1,23 @@
 # .. so that includes of hstore/hstore.h work
 hstore_inc = include_directories('.', '../')
 
+hstore_sources = files(
+  'hstore_compat.c',
+  'hstore_gin.c',
+  'hstore_gist.c',
+  'hstore_io.c',
+  'hstore_op.c',
+  'hstore_subs.c',
+)
+
+if host_system == 'windows'
+  hstore_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'hstore',
+    '--FILEDESC', 'hstore - key/value pair data type',])
+endif
+
 hstore = shared_module('hstore',
-  files(
-    'hstore_compat.c',
-    'hstore_gin.c',
-    'hstore_gist.c',
-    'hstore_io.c',
-    'hstore_op.c',
-    'hstore_subs.c',
-  ),
+  hstore_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += hstore
diff --git a/contrib/hstore_plperl/meson.build b/contrib/hstore_plperl/meson.build
index bbafa0221bd..a238fee6a26 100644
--- a/contrib/hstore_plperl/meson.build
+++ b/contrib/hstore_plperl/meson.build
@@ -6,6 +6,12 @@ hstore_plperl_sources = files(
   'hstore_plperl.c',
 )
 
+if host_system == 'windows'
+  hstore_plperl_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'hstore_plperl',
+    '--FILEDESC', 'hstore_plperl - hstore transform for plperl',])
+endif
+
 hstore_plperl = shared_module('hstore_plperl',
   hstore_plperl_sources,
   include_directories: [plperl_inc, hstore_inc],
diff --git a/contrib/hstore_plpython/meson.build b/contrib/hstore_plpython/meson.build
index 214b48519a9..6071aaeb4b3 100644
--- a/contrib/hstore_plpython/meson.build
+++ b/contrib/hstore_plpython/meson.build
@@ -6,6 +6,12 @@ hstore_plpython_sources = files(
   'hstore_plpython.c',
 )
 
+if host_system == 'windows'
+  hstore_plpython_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'hstore_plpython3',
+    '--FILEDESC', 'hstore_plpython - hstore transform for plpython',])
+endif
+
 hstore_plpython = shared_module('hstore_plpython3',
   hstore_plpython_sources,
   include_directories: [plpython_inc, hstore_inc, ],
diff --git a/contrib/intarray/meson.build b/contrib/intarray/meson.build
index 1655bcbb3fd..b7cf1ce0cad 100644
--- a/contrib/intarray/meson.build
+++ b/contrib/intarray/meson.build
@@ -8,6 +8,12 @@ intarray_sources = files(
   '_intbig_gist.c',
 )
 
+if host_system == 'windows'
+  intarray_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', '_int',
+    '--FILEDESC', 'intarray - functions and operators for arrays of integers',])
+endif
+
 intarray = shared_module('_int',
   intarray_sources,
   kwargs: contrib_mod_args,
diff --git a/contrib/isn/meson.build b/contrib/isn/meson.build
index cc30bbeb55c..db68a718313 100644
--- a/contrib/isn/meson.build
+++ b/contrib/isn/meson.build
@@ -2,6 +2,12 @@ isn_sources = files(
   'isn.c',
 )
 
+if host_system == 'windows'
+  isn_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'isn',
+    '--FILEDESC', 'isn - data types for international product numbering standards',])
+endif
+
 isn = shared_module('isn',
   isn_sources,
   kwargs: contrib_mod_args,
diff --git a/contrib/jsonb_plperl/meson.build b/contrib/jsonb_plperl/meson.build
index 5c915d8ed94..071a7a98d2c 100644
--- a/contrib/jsonb_plperl/meson.build
+++ b/contrib/jsonb_plperl/meson.build
@@ -6,6 +6,12 @@ jsonb_plperl_sources = files(
   'jsonb_plperl.c',
 )
 
+if host_system == 'windows'
+  jsonb_plperl_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'jsonb_plperl',
+    '--FILEDESC', 'jsonb_plperl - jsonb transform for plperl',])
+endif
+
 jsonb_plperl = shared_module('jsonb_plperl',
   jsonb_plperl_sources,
   include_directories: [plperl_inc],
diff --git a/contrib/jsonb_plpython/meson.build b/contrib/jsonb_plpython/meson.build
index de8e1105c6a..84dc1161e8b 100644
--- a/contrib/jsonb_plpython/meson.build
+++ b/contrib/jsonb_plpython/meson.build
@@ -6,6 +6,12 @@ jsonb_plpython_sources = files(
   'jsonb_plpython.c',
 )
 
+if host_system == 'windows'
+  jsonb_plpython_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'jsonb_plpython3',
+    '--FILEDESC', 'jsonb_plpython - jsonb transform for plpython',])
+endif
+
 jsonb_plpython = shared_module('jsonb_plpython3',
   jsonb_plpython_sources,
   include_directories: [plpython_inc],
diff --git a/contrib/lo/meson.build b/contrib/lo/meson.build
index 9082d5713c7..61ae131f1cc 100644
--- a/contrib/lo/meson.build
+++ b/contrib/lo/meson.build
@@ -2,6 +2,12 @@ lo_sources = files(
   'lo.c',
 )
 
+if host_system == 'windows'
+  lo_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'lo',
+    '--FILEDESC', 'lo - management for large objects',])
+endif
+
 lo = shared_module('lo',
   lo_sources,
   kwargs: contrib_mod_args,
diff --git a/contrib/ltree/meson.build b/contrib/ltree/meson.build
index 9463fc2c5e5..421292cea9d 100644
--- a/contrib/ltree/meson.build
+++ b/contrib/ltree/meson.build
@@ -13,6 +13,12 @@ ltree_sources = files(
 # .. so that includes of ltree/ltree.h work
 ltree_inc = include_directories('.', '../')
 
+if host_system == 'windows'
+  ltree_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'ltree',
+    '--FILEDESC', 'ltree - hierarchical label data type',])
+endif
+
 ltree = shared_module('ltree',
   ltree_sources,
   kwargs: contrib_mod_args,
diff --git a/contrib/ltree_plpython/meson.build b/contrib/ltree_plpython/meson.build
index 429d75006aa..acf5e4a6fc8 100644
--- a/contrib/ltree_plpython/meson.build
+++ b/contrib/ltree_plpython/meson.build
@@ -6,6 +6,12 @@ ltree_plpython_sources = files(
   'ltree_plpython.c',
 )
 
+if host_system == 'windows'
+  ltree_plpython_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'ltree_plpython3',
+    '--FILEDESC', 'ltree_plpython - ltree transform for plpython',])
+endif
+
 ltree_plpython = shared_module('ltree_plpython3',
   ltree_plpython_sources,
   include_directories: [plpython_inc, ltree_inc],
diff --git a/contrib/oid2name/meson.build b/contrib/oid2name/meson.build
index 1dad5d8f6e7..1a248f19260 100644
--- a/contrib/oid2name/meson.build
+++ b/contrib/oid2name/meson.build
@@ -1,5 +1,15 @@
+oid2name_sources = files(
+  'oid2name.c',
+)
+
+if host_system == 'windows'
+  oid2name_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'oid2name',
+    '--FILEDESC', 'oid2name - examine the file structure',])
+endif
+
 oid2name = executable('oid2name',
-  ['oid2name.c'],
+  oid2name_sources,
   dependencies: [frontend_code, libpq],
   kwargs: default_bin_args,
 )
diff --git a/contrib/old_snapshot/meson.build b/contrib/old_snapshot/meson.build
index 8e7ee09a43a..77276c3715a 100644
--- a/contrib/old_snapshot/meson.build
+++ b/contrib/old_snapshot/meson.build
@@ -2,6 +2,12 @@ old_snapshot_sources = files(
   'time_mapping.c',
 )
 
+if host_system == 'windows'
+  old_snapshot_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'old_snapshot',
+    '--FILEDESC', 'old_snapshot - utilities in support of old_snapshot_threshold',])
+endif
+
 old_snapshot = shared_module('old_snapshot',
   old_snapshot_sources,
   kwargs: contrib_mod_args,
diff --git a/contrib/pageinspect/meson.build b/contrib/pageinspect/meson.build
index 4af8153e4fd..3ec50b9445e 100644
--- a/contrib/pageinspect/meson.build
+++ b/contrib/pageinspect/meson.build
@@ -9,6 +9,12 @@ pageinspect_sources = files(
   'rawpage.c',
 )
 
+if host_system == 'windows'
+  pageinspect_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pageinspect',
+    '--FILEDESC', 'pageinspect - functions to inspect contents of database pages',])
+endif
+
 pageinspect = shared_module('pageinspect',
   pageinspect_sources,
   kwargs: contrib_mod_args,
diff --git a/contrib/passwordcheck/meson.build b/contrib/passwordcheck/meson.build
index 7da47d02f1d..383d7df372a 100644
--- a/contrib/passwordcheck/meson.build
+++ b/contrib/passwordcheck/meson.build
@@ -9,6 +9,12 @@ passwordcheck_deps = []
 # passwordcheck_c_args += ['-DUSE_CRACKLIB', '-DCRACKLIB_DICTPATH="/usr/lib/cracklib_dict"']
 # passwordcheck_deps += [cc.find_library('crack')]
 
+if host_system == 'windows'
+  passwordcheck_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'passwordcheck',
+    '--FILEDESC', 'passwordcheck - strengthen user password checks',])
+endif
+
 passwordcheck = shared_module('passwordcheck',
   passwordcheck_sources,
   c_args: passwordcheck_c_args,
diff --git a/contrib/pg_buffercache/meson.build b/contrib/pg_buffercache/meson.build
index 2c69eae3ea2..dd9948e5f0b 100644
--- a/contrib/pg_buffercache/meson.build
+++ b/contrib/pg_buffercache/meson.build
@@ -1,7 +1,15 @@
+pg_buffercache_sources = files(
+  'pg_buffercache_pages.c',
+)
+
+if host_system == 'windows'
+  pg_buffercache_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_buffercache',
+    '--FILEDESC', 'pg_buffercache - monitoring of shared buffer cache in real-time',])
+endif
+
 pg_buffercache = shared_module('pg_buffercache',
-  files(
-    'pg_buffercache_pages.c',
-  ),
+  pg_buffercache_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += pg_buffercache
diff --git a/contrib/pg_freespacemap/meson.build b/contrib/pg_freespacemap/meson.build
index f795014d7ca..904b37b6e9b 100644
--- a/contrib/pg_freespacemap/meson.build
+++ b/contrib/pg_freespacemap/meson.build
@@ -1,7 +1,15 @@
+pg_freespacemap_sources = files(
+  'pg_freespacemap.c',
+)
+
+if host_system == 'windows'
+  pg_freespacemap_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_freespacemap',
+    '--FILEDESC', 'pg_freespacemap - monitoring of free space map',])
+endif
+
 pg_freespacemap = shared_module('pg_freespacemap',
-  files(
-    'pg_freespacemap.c',
-  ),
+  pg_freespacemap_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += pg_freespacemap
diff --git a/contrib/pg_prewarm/meson.build b/contrib/pg_prewarm/meson.build
index bdca9af4f27..b7140cee34b 100644
--- a/contrib/pg_prewarm/meson.build
+++ b/contrib/pg_prewarm/meson.build
@@ -1,8 +1,16 @@
+pg_prewarm_sources = files(
+  'autoprewarm.c',
+  'pg_prewarm.c',
+)
+
+if host_system == 'windows'
+  pg_prewarm_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_prewarm',
+    '--FILEDESC', 'pg_prewarm - preload relation data into system buffer cache',])
+endif
+
 pg_prewarm = shared_module('pg_prewarm',
-  files(
-    'autoprewarm.c',
-    'pg_prewarm.c',
-  ),
+  pg_prewarm_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += pg_prewarm
diff --git a/contrib/pg_stat_statements/meson.build b/contrib/pg_stat_statements/meson.build
index ac117d2fc1d..854df138e76 100644
--- a/contrib/pg_stat_statements/meson.build
+++ b/contrib/pg_stat_statements/meson.build
@@ -1,5 +1,15 @@
+pg_stat_statements_sources = files(
+  'pg_stat_statements.c',
+)
+
+if host_system == 'windows'
+  pg_stat_statements_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_stat_statements',
+    '--FILEDESC', 'pg_stat_statements - execution statistics of SQL statements',])
+endif
+
 pg_stat_statements = shared_module('pg_stat_statements',
-  files('pg_stat_statements.c'),
+  pg_stat_statements_sources,
   kwargs: contrib_mod_args + {
     'dependencies': contrib_mod_args['dependencies'],
   },
diff --git a/contrib/pg_surgery/meson.build b/contrib/pg_surgery/meson.build
index ac71caa5276..7b5c5999f4b 100644
--- a/contrib/pg_surgery/meson.build
+++ b/contrib/pg_surgery/meson.build
@@ -1,7 +1,15 @@
+pg_surgery_sources = files(
+  'heap_surgery.c',
+)
+
+if host_system == 'windows'
+  pg_surgery_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_surgery',
+    '--FILEDESC', 'pg_surgery - perform surgery on a damaged relation',])
+endif
+
 pg_surgery = shared_module('pg_surgery',
-  files(
-    'heap_surgery.c',
-  ),
+  pg_surgery_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += pg_surgery
diff --git a/contrib/pg_trgm/meson.build b/contrib/pg_trgm/meson.build
index a90628d23c6..c8c7c07b308 100644
--- a/contrib/pg_trgm/meson.build
+++ b/contrib/pg_trgm/meson.build
@@ -1,10 +1,18 @@
+pg_trgm_sources = files(
+  'trgm_gin.c',
+  'trgm_gist.c',
+  'trgm_op.c',
+  'trgm_regexp.c',
+)
+
+if host_system == 'windows'
+  pg_trgm_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_trgm',
+    '--FILEDESC', 'pg_trgm - trigram matching',])
+endif
+
 pg_trgm = shared_module('pg_trgm',
-  files(
-    'trgm_gin.c',
-    'trgm_gist.c',
-    'trgm_op.c',
-    'trgm_regexp.c',
-  ),
+  pg_trgm_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += pg_trgm
diff --git a/contrib/pg_visibility/meson.build b/contrib/pg_visibility/meson.build
index 933dc99ac4d..263a0d08b82 100644
--- a/contrib/pg_visibility/meson.build
+++ b/contrib/pg_visibility/meson.build
@@ -1,7 +1,15 @@
+pg_visibility_sources = files(
+  'pg_visibility.c',
+)
+
+if host_system == 'windows'
+  pg_visibility_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_visibility',
+    '--FILEDESC', 'pg_visibility - page visibility information',])
+endif
+
 pg_visibility = shared_module('pg_visibility',
-  files(
-    'pg_visibility.c',
-  ),
+  pg_visibility_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += pg_visibility
diff --git a/contrib/pg_walinspect/meson.build b/contrib/pg_walinspect/meson.build
index d6b27877dd0..4314a3182a2 100644
--- a/contrib/pg_walinspect/meson.build
+++ b/contrib/pg_walinspect/meson.build
@@ -1,5 +1,11 @@
 pg_walinspect_sources = files('pg_walinspect.c')
 
+if host_system == 'windows'
+  pg_walinspect_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_walinspect',
+    '--FILEDESC', 'pg_walinspect - functions to inspect contents of PostgreSQL Write-Ahead Log',])
+endif
+
 pg_walinspect = shared_module('pg_walinspect',
   pg_walinspect_sources,
   kwargs: contrib_mod_args + {
diff --git a/contrib/pgcrypto/meson.build b/contrib/pgcrypto/meson.build
index fe0851bf8e8..7fc7bbc7ca1 100644
--- a/contrib/pgcrypto/meson.build
+++ b/contrib/pgcrypto/meson.build
@@ -69,6 +69,12 @@ else
   pgcrypto_regress += 'pgp-zlib-DISABLED'
 endif
 
+if host_system == 'windows'
+  pgcrypto_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pgcrypto',
+    '--FILEDESC', 'pgcrypto - cryptographic functions',])
+endif
+
 pgcrypto = shared_module('pgcrypto',
   pgcrypto_sources,
   link_with: pgcrypto_link_with,
diff --git a/contrib/pgrowlocks/meson.build b/contrib/pgrowlocks/meson.build
index 1b41691a2a3..8092f0d4a64 100644
--- a/contrib/pgrowlocks/meson.build
+++ b/contrib/pgrowlocks/meson.build
@@ -1,7 +1,15 @@
+pgrowlocks_sources = files(
+  'pgrowlocks.c',
+)
+
+if host_system == 'windows'
+  pgrowlocks_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pgrowlocks',
+    '--FILEDESC', 'pgrowlocks - display row locking information',])
+endif
+
 pgrowlocks = shared_module('pgrowlocks',
-  files(
-    'pgrowlocks.c',
-  ),
+  pgrowlocks_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += pgrowlocks
diff --git a/contrib/pgstattuple/meson.build b/contrib/pgstattuple/meson.build
index 8e828692d5c..05e4cd46a5c 100644
--- a/contrib/pgstattuple/meson.build
+++ b/contrib/pgstattuple/meson.build
@@ -1,9 +1,17 @@
+pgstattuple_sources = files(
+  'pgstatapprox.c',
+  'pgstatindex.c',
+  'pgstattuple.c',
+)
+
+if host_system == 'windows'
+  pgstattuple_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pgstattuple',
+    '--FILEDESC', 'pgstattuple - tuple-level statistics',])
+endif
+
 pgstattuple = shared_module('pgstattuple',
-  files(
-    'pgstatapprox.c',
-    'pgstatindex.c',
-    'pgstattuple.c',
-  ),
+  pgstattuple_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += pgstattuple
diff --git a/contrib/postgres_fdw/meson.build b/contrib/postgres_fdw/meson.build
index 378885ec93b..d3746ff135c 100644
--- a/contrib/postgres_fdw/meson.build
+++ b/contrib/postgres_fdw/meson.build
@@ -6,6 +6,12 @@ postgres_fdw_sources = files(
   'shippable.c',
 )
 
+if host_system == 'windows'
+  postgres_fdw_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'postgres_fdw',
+    '--FILEDESC', 'postgres_fdw - foreign data wrapper for PostgreSQL',])
+endif
+
 postgres_fdw = shared_module('postgres_fdw',
   postgres_fdw_sources,
   kwargs: contrib_mod_args + {
diff --git a/contrib/seg/meson.build b/contrib/seg/meson.build
index e476eab2a77..c6fbb22999b 100644
--- a/contrib/seg/meson.build
+++ b/contrib/seg/meson.build
@@ -17,6 +17,12 @@ seg_parse = custom_target('segparse',
 generated_sources += seg_parse.to_list()
 seg_sources += seg_parse
 
+if host_system == 'windows'
+  seg_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'seg',
+    '--FILEDESC', 'seg - line segment data type',])
+endif
+
 seg = shared_module('seg',
   seg_sources,
   include_directories: include_directories('.'),
diff --git a/contrib/sepgsql/meson.build b/contrib/sepgsql/meson.build
index 60a95e17c2f..8bef239e3c2 100644
--- a/contrib/sepgsql/meson.build
+++ b/contrib/sepgsql/meson.build
@@ -14,6 +14,12 @@ sepgsql_sources = files(
   'uavc.c',
 )
 
+if host_system == 'windows'
+  sepgsql_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'sepgsql',
+    '--FILEDESC', 'sepgsql - SELinux integration',])
+endif
+
 sepgsql = shared_module('sepgsql',
   sepgsql_sources,
   kwargs: contrib_mod_args + {
diff --git a/contrib/spi/meson.build b/contrib/spi/meson.build
index 98008980ec2..e7d78189ef5 100644
--- a/contrib/spi/meson.build
+++ b/contrib/spi/meson.build
@@ -1,5 +1,15 @@
+autoinc_sources = files(
+  'autoinc.c',
+)
+
+if host_system == 'windows'
+  autoinc_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'autoinc',
+    '--FILEDESC', 'spi - examples of using SPI and triggers',])
+endif
+
 autoinc = shared_module('autoinc',
-  ['autoinc.c'],
+  autoinc_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += autoinc
@@ -9,8 +19,18 @@ install_data('autoinc.control', 'autoinc--1.0.sql',
 )
 
 
+insert_username_sources = files(
+  'insert_username.c',
+)
+
+if host_system == 'windows'
+  insert_username_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'insert_username',
+    '--FILEDESC', 'spi - examples of using SPI and triggers',])
+endif
+
 insert_username = shared_module('insert_username',
-  ['insert_username.c'],
+  insert_username_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += insert_username
@@ -22,8 +42,18 @@ install_data(
 )
 
 
+moddatetime_sources = files(
+  'moddatetime.c',
+)
+
+if host_system == 'windows'
+  moddatetime_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'moddatetime',
+    '--FILEDESC', 'spi - examples of using SPI and triggers',])
+endif
+
 moddatetime = shared_module('moddatetime',
-  ['moddatetime.c'],
+  moddatetime_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += moddatetime
@@ -38,8 +68,18 @@ install_data(
 # comment out if you want a quieter refint package for other uses
 refint_cflags = ['-DREFINT_VERBOSE']
 
+refint_sources = files(
+  'refint.c',
+)
+
+if host_system == 'windows'
+  refint_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'refint',
+    '--FILEDESC', 'spi - examples of using SPI and triggers',])
+endif
+
 refint = shared_module('refint',
-  ['refint.c'],
+  refint_sources,
   c_args: refint_cflags,
   kwargs: contrib_mod_args,
 )
diff --git a/contrib/sslinfo/meson.build b/contrib/sslinfo/meson.build
index 53f752a08ac..136983e783d 100644
--- a/contrib/sslinfo/meson.build
+++ b/contrib/sslinfo/meson.build
@@ -2,10 +2,18 @@ if not ssl.found()
   subdir_done()
 endif
 
+sslinfo_sources = files(
+  'sslinfo.c',
+)
+
+if host_system == 'windows'
+  sslinfo_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'sslinfo',
+    '--FILEDESC', 'sslinfo - information about client SSL certificate',])
+endif
+
 sslinfo = shared_module('sslinfo',
-  files(
-    'sslinfo.c',
-  ),
+  sslinfo_sources,
   kwargs: contrib_mod_args + {
     'dependencies': [ssl, contrib_mod_args['dependencies']],
   }
diff --git a/contrib/tablefunc/meson.build b/contrib/tablefunc/meson.build
index f4230096c0c..d2ddc8d3b39 100644
--- a/contrib/tablefunc/meson.build
+++ b/contrib/tablefunc/meson.build
@@ -1,7 +1,15 @@
+tablefunc_sources = files(
+  'tablefunc.c',
+)
+
+if host_system == 'windows'
+  tablefunc_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'tablefunc',
+    '--FILEDESC', 'tablefunc - various functions that return tables',])
+endif
+
 tablefunc = shared_module('tablefunc',
-  files(
-    'tablefunc.c',
-  ),
+  tablefunc_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += tablefunc
diff --git a/contrib/tcn/meson.build b/contrib/tcn/meson.build
index c3a025247d4..71261c3b0a2 100644
--- a/contrib/tcn/meson.build
+++ b/contrib/tcn/meson.build
@@ -1,7 +1,15 @@
+tcn_sources = files(
+  'tcn.c',
+)
+
+if host_system == 'windows'
+  tcn_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'tcn',
+    '--FILEDESC', 'tcn - trigger function notifying listeners',])
+endif
+
 tcn = shared_module('tcn',
-  files(
-    'tcn.c',
-  ),
+  tcn_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += tcn
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index dd7cb0101ad..6376103c689 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -2,6 +2,12 @@ test_decoding_sources = files(
   'test_decoding.c',
 )
 
+if host_system == 'windows'
+  test_decoding_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'test_decoding',
+    '--FILEDESC', 'test_decoding - example of a logical decoding output plugin',])
+endif
+
 test_decoding = shared_module('test_decoding',
   test_decoding_sources,
   kwargs: contrib_mod_args,
diff --git a/contrib/tsm_system_rows/meson.build b/contrib/tsm_system_rows/meson.build
index b9cd42115a8..380abb49883 100644
--- a/contrib/tsm_system_rows/meson.build
+++ b/contrib/tsm_system_rows/meson.build
@@ -1,7 +1,15 @@
+tsm_system_rows_sources = files(
+  'tsm_system_rows.c',
+)
+
+if host_system == 'windows'
+  tsm_system_rows_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'tsm_system_rows',
+    '--FILEDESC', 'tsm_system_rows - TABLESAMPLE method which accepts number of rows as a limit',])
+endif
+
 tsm_system_rows = shared_module('tsm_system_rows',
-  files(
-    'tsm_system_rows.c',
-  ),
+  tsm_system_rows_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += tsm_system_rows
diff --git a/contrib/tsm_system_time/meson.build b/contrib/tsm_system_time/meson.build
index 18015912ffb..e57a2702c60 100644
--- a/contrib/tsm_system_time/meson.build
+++ b/contrib/tsm_system_time/meson.build
@@ -1,7 +1,15 @@
+tsm_system_time_sources = files(
+  'tsm_system_time.c',
+)
+
+if host_system == 'windows'
+  tsm_system_time_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'tsm_system_time',
+    '--FILEDESC', 'tsm_system_time - TABLESAMPLE method which accepts time in milliseconds as a limit',])
+endif
+
 tsm_system_time = shared_module('tsm_system_time',
-  files(
-    'tsm_system_time.c',
-  ),
+  tsm_system_time_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += tsm_system_time
diff --git a/contrib/unaccent/meson.build b/contrib/unaccent/meson.build
index 872b76e3223..438035132f8 100644
--- a/contrib/unaccent/meson.build
+++ b/contrib/unaccent/meson.build
@@ -1,7 +1,15 @@
+unaccent_sources = files(
+  'unaccent.c',
+)
+
+if host_system == 'windows'
+  unaccent_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'unaccent',
+    '--FILEDESC', 'unaccent - text search dictionary that removes accents',])
+endif
+
 unaccent = shared_module('unaccent',
-  files(
-    'unaccent.c',
-  ),
+  unaccent_sources,
   kwargs: contrib_mod_args,
 )
 contrib_targets += unaccent
diff --git a/contrib/uuid-ossp/meson.build b/contrib/uuid-ossp/meson.build
index da6d1d75c12..28730f398f0 100644
--- a/contrib/uuid-ossp/meson.build
+++ b/contrib/uuid-ossp/meson.build
@@ -2,10 +2,18 @@ if not uuid.found()
   subdir_done()
 endif
 
+uuid_ossp_sources = files(
+  'uuid-ossp.c',
+)
+
+if host_system == 'windows'
+  uuid_ossp_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'uuid-ossp',
+    '--FILEDESC', 'uuid-ossp - UUID generation',])
+endif
+
 uuid_ossp = shared_module('uuid-ossp',
-  files(
-    'uuid-ossp.c',
-  ),
+  uuid_ossp_sources,
   kwargs: contrib_mod_args + {
     'dependencies': [uuid, contrib_mod_args['dependencies']],
   },
diff --git a/contrib/vacuumlo/meson.build b/contrib/vacuumlo/meson.build
index 7a632b87d1b..846de47dbd1 100644
--- a/contrib/vacuumlo/meson.build
+++ b/contrib/vacuumlo/meson.build
@@ -1,5 +1,15 @@
+vacuumlo_sources = files(
+  'vacuumlo.c',
+)
+
+if host_system == 'windows'
+  vacuumlo_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'vacuumlo',
+    '--FILEDESC', 'vacuumlo - removes orphaned large objects',])
+endif
+
 vacuumlo = executable('vacuumlo',
-  ['vacuumlo.c'],
+  vacuumlo_sources,
   dependencies: [frontend_code, libpq],
   kwargs: default_bin_args,
 )
diff --git a/contrib/xml2/meson.build b/contrib/xml2/meson.build
index 9c0b56f01f6..89b0d677516 100644
--- a/contrib/xml2/meson.build
+++ b/contrib/xml2/meson.build
@@ -2,11 +2,19 @@ if not libxml.found()
   subdir_done()
 endif
 
+xml2_sources = files(
+  'xpath.c',
+  'xslt_proc.c',
+)
+
+if host_system == 'windows'
+  xml2_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pgxml',
+    '--FILEDESC', 'xml2 - XPath querying and XSLT',])
+endif
+
 xml2 = shared_module('pgxml',
-  files(
-    'xpath.c',
-    'xslt_proc.c',
-  ),
+  xml2_sources,
   kwargs: contrib_mod_args + {
     'dependencies': [libxml, libxslt, contrib_mod_args['dependencies']],
   },
diff --git a/src/interfaces/ecpg/compatlib/meson.build b/src/interfaces/ecpg/compatlib/meson.build
index b803000c708..4d6454381b5 100644
--- a/src/interfaces/ecpg/compatlib/meson.build
+++ b/src/interfaces/ecpg/compatlib/meson.build
@@ -7,6 +7,12 @@ ecpg_compat_inc = [include_directories('.'), ecpg_inc, libpq_inc]
 ecpg_compat_c_args = ['-DSO_MAJOR_VERSION=3']
 export_file = custom_target('libecpg_compat.exports', kwargs: gen_export_kwargs)
 
+if host_system == 'windows'
+  ecpg_compat_so_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'libecpg_compat',
+    '--FILEDESC', 'ECPG compat - compatibility library for ECPG',])
+endif
+
 # see src/interfaces/libpq/meson.build
 ecpg_compat_st = static_library('libecpg_compat',
   ecpg_compat_sources,
diff --git a/src/interfaces/ecpg/ecpglib/meson.build b/src/interfaces/ecpg/ecpglib/meson.build
index 6fdf019149c..7e6e6fbf5c0 100644
--- a/src/interfaces/ecpg/ecpglib/meson.build
+++ b/src/interfaces/ecpg/ecpglib/meson.build
@@ -16,6 +16,12 @@ ecpglib_inc = [include_directories('.'), ecpg_inc]
 ecpglib_c_args = ['-DSO_MAJOR_VERSION=6']
 export_file = custom_target('libecpg.exports', kwargs: gen_export_kwargs)
 
+if host_system == 'windows'
+  ecpglib_so_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'libecpg',
+    '--FILEDESC', 'ECPG - embedded SQL in C',])
+endif
+
 # see src/interfaces/libpq/meson.build
 ecpglib_st = static_library('libecpg',
   ecpglib_sources,
diff --git a/src/interfaces/ecpg/pgtypeslib/meson.build b/src/interfaces/ecpg/pgtypeslib/meson.build
index 8e5d235810a..530dd2c602d 100644
--- a/src/interfaces/ecpg/pgtypeslib/meson.build
+++ b/src/interfaces/ecpg/pgtypeslib/meson.build
@@ -12,6 +12,12 @@ export_file = custom_target('libpgtypes.exports', kwargs: gen_export_kwargs)
 ecpg_pgtypes_inc = [include_directories('.'), ecpg_inc]
 ecpg_pgtypes_c_args = ['-DSO_MAJOR_VERSION=3']
 
+if host_system == 'windows'
+  ecpg_pgtypes_so_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pgtypes',
+    '--FILEDESC', 'pgtypes - library for data type mapping',])
+endif
+
 # see src/interfaces/libpq/meson.build
 ecpg_pgtypes_st = static_library('libpgtypes',
   ecpg_pgtypes_sources,
diff --git a/src/interfaces/ecpg/preproc/meson.build b/src/interfaces/ecpg/preproc/meson.build
index 1be49c8c27f..74876f039c9 100644
--- a/src/interfaces/ecpg/preproc/meson.build
+++ b/src/interfaces/ecpg/preproc/meson.build
@@ -93,6 +93,12 @@ ecpg_kwlist = custom_target('ecpg_kwlist_d.h',
 generated_sources += ecpg_kwlist
 ecpg_sources += ecpg_kwlist
 
+if host_system == 'windows'
+  ecpg_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'ecpg',
+    '--FILEDESC', 'ecpg - embedded SQL precompiler for C',])
+endif
+
 ecpg_exe = executable('ecpg',
   ecpg_sources,
   include_directories: ['.', ecpg_inc, postgres_inc, libpq_inc],
diff --git a/src/interfaces/ecpg/test/meson.build b/src/interfaces/ecpg/test/meson.build
index 8904aa7fd90..94b26d10314 100644
--- a/src/interfaces/ecpg/test/meson.build
+++ b/src/interfaces/ecpg/test/meson.build
@@ -7,6 +7,11 @@ pg_regress_ecpg_sources = pg_regress_c + files(
   'pg_regress_ecpg.c',
 )
 
+if host_system == 'windows'
+  pg_regress_ecpg_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_regress_ecpg',])
+endif
+
 pg_regress_ecpg = executable('pg_regress_ecpg',
   pg_regress_ecpg_sources,
   c_args: pg_regress_cflags,
diff --git a/src/test/isolation/meson.build b/src/test/isolation/meson.build
index c7656fd4609..ba27b8c1d44 100644
--- a/src/test/isolation/meson.build
+++ b/src/test/isolation/meson.build
@@ -23,6 +23,12 @@ spec_parser = custom_target('specparse',
 isolationtester_sources += spec_parser
 generated_sources += spec_parser.to_list()
 
+if host_system == 'windows'
+  isolation_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_isolation_regress',
+    '--FILEDESC', 'pg_isolation_regress - multi-client test driver',])
+endif
+
 pg_isolation_regress = executable('pg_isolation_regress',
   isolation_sources,
   c_args: pg_regress_cflags,
@@ -34,6 +40,13 @@ pg_isolation_regress = executable('pg_isolation_regress',
 )
 bin_targets += pg_isolation_regress
 
+
+if host_system == 'windows'
+  isolationtester_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'isolationtester',
+    '--FILEDESC', 'isolationtester - multi-client test driver',])
+endif
+
 isolationtester = executable('isolationtester',
   isolationtester_sources,
   include_directories: include_directories('.'),
diff --git a/src/test/modules/delay_execution/meson.build b/src/test/modules/delay_execution/meson.build
index cf4bdaba637..a0c3ab6afe7 100644
--- a/src/test/modules/delay_execution/meson.build
+++ b/src/test/modules/delay_execution/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+delay_execution_sources = files(
+  'delay_execution.c',
+)
+
+if host_system == 'windows'
+  delay_execution_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'delay_execution',
+    '--FILEDESC', 'delay_execution - allow delay between parsing and execution',])
+endif
+
 delay_execution = shared_module('delay_execution',
-  ['delay_execution.c'],
+  delay_execution_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += delay_execution
diff --git a/src/test/modules/dummy_index_am/meson.build b/src/test/modules/dummy_index_am/meson.build
index 56ff5f48001..4ce82491135 100644
--- a/src/test/modules/dummy_index_am/meson.build
+++ b/src/test/modules/dummy_index_am/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+dummy_index_am_sources = files(
+  'dummy_index_am.c',
+)
+
+if host_system == 'windows'
+  dummy_index_am_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'dummy_index_am',
+    '--FILEDESC', 'dummy_index_am - index access method template',])
+endif
+
 dummy_index_am = shared_module('dummy_index_am',
-  ['dummy_index_am.c'],
+  dummy_index_am_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += dummy_index_am
diff --git a/src/test/modules/dummy_seclabel/meson.build b/src/test/modules/dummy_seclabel/meson.build
index 21b7cf8f353..81b626e496c 100644
--- a/src/test/modules/dummy_seclabel/meson.build
+++ b/src/test/modules/dummy_seclabel/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+dummy_seclabel_sources = files(
+  'dummy_seclabel.c',
+)
+
+if host_system == 'windows'
+  dummy_seclabel_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'dummy_seclabel',
+    '--FILEDESC', 'dummy_seclabel - regression testing of the SECURITY LABEL statement',])
+endif
+
 dummy_seclabel = shared_module('dummy_seclabel',
-  ['dummy_seclabel.c'],
+  dummy_seclabel_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += dummy_seclabel
diff --git a/src/test/modules/libpq_pipeline/meson.build b/src/test/modules/libpq_pipeline/meson.build
index 8384b6e3b2a..de0e2d15626 100644
--- a/src/test/modules/libpq_pipeline/meson.build
+++ b/src/test/modules/libpq_pipeline/meson.build
@@ -1,7 +1,15 @@
+libpq_pipeline_sources = files(
+  'libpq_pipeline.c',
+)
+
+if host_system == 'windows'
+  libpq_pipeline_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'libpq_pipeline',
+    '--FILEDESC', 'libpq_pipeline - test program for pipeline execution',])
+endif
+
 libpq_pipeline = executable('libpq_pipeline',
-  files(
-    'libpq_pipeline.c',
-  ),
+  libpq_pipeline_sources,
   dependencies: [frontend_code, libpq],
   kwargs: default_bin_args + {
     'install': false,
diff --git a/src/test/modules/plsample/meson.build b/src/test/modules/plsample/meson.build
index 45de3f1990d..e1ea2c7a16f 100644
--- a/src/test/modules/plsample/meson.build
+++ b/src/test/modules/plsample/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+plsample_sources = files(
+  'plsample.c',
+)
+
+if host_system == 'windows'
+  plsample_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'plsample',
+    '--FILEDESC', 'PL/Sample - template for procedural language',])
+endif
+
 plsample = shared_module('plsample',
-  ['plsample.c'],
+  plsample_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += plsample
diff --git a/src/test/modules/spgist_name_ops/meson.build b/src/test/modules/spgist_name_ops/meson.build
index 857fc7e140e..445296fee0b 100644
--- a/src/test/modules/spgist_name_ops/meson.build
+++ b/src/test/modules/spgist_name_ops/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+spgist_name_ops_sources = files(
+  'spgist_name_ops.c',
+)
+
+if host_system == 'windows'
+  spgist_name_ops_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'spgist_name_ops',
+    '--FILEDESC', 'spgist_name_ops - test opclass for SP-GiST',])
+endif
+
 spgist_name_ops = shared_module('spgist_name_ops',
-  ['spgist_name_ops.c'],
+  spgist_name_ops_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += spgist_name_ops
diff --git a/src/test/modules/ssl_passphrase_callback/meson.build b/src/test/modules/ssl_passphrase_callback/meson.build
index a57bd0693a3..a9eb4c564da 100644
--- a/src/test/modules/ssl_passphrase_callback/meson.build
+++ b/src/test/modules/ssl_passphrase_callback/meson.build
@@ -3,8 +3,19 @@ if not ssl.found()
 endif
 
 # FIXME: prevent install during main install, but not during test :/
+
+ssl_passphrase_callback_sources = files(
+  'ssl_passphrase_func.c',
+)
+
+if host_system == 'windows'
+  ssl_passphrase_callback_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'ssl_passphrase_func',
+    '--FILEDESC', 'callback function to provide a passphrase',])
+endif
+
 ssl_passphrase_callback = shared_module('ssl_passphrase_func',
-  ['ssl_passphrase_func.c'],
+  ssl_passphrase_callback_sources,
   kwargs: pg_mod_args + {
     'dependencies': [ssl, pg_mod_args['dependencies']],
   },
diff --git a/src/test/modules/test_bloomfilter/meson.build b/src/test/modules/test_bloomfilter/meson.build
index 945eb5a70c4..3cf6b05754f 100644
--- a/src/test/modules/test_bloomfilter/meson.build
+++ b/src/test/modules/test_bloomfilter/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+test_bloomfilter_sources = files(
+  'test_bloomfilter.c',
+)
+
+if host_system == 'windows'
+  test_bloomfilter_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'test_bloomfilter',
+    '--FILEDESC', 'test_bloomfilter - test code for Bloom filter library',])
+endif
+
 test_bloomfilter = shared_module('test_bloomfilter',
-  ['test_bloomfilter.c'],
+  test_bloomfilter_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += test_bloomfilter
diff --git a/src/test/modules/test_ddl_deparse/meson.build b/src/test/modules/test_ddl_deparse/meson.build
index 81ad5adc526..54d44f9b2b4 100644
--- a/src/test/modules/test_ddl_deparse/meson.build
+++ b/src/test/modules/test_ddl_deparse/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+test_ddl_deparse_sources = files(
+  'test_ddl_deparse.c',
+)
+
+if host_system == 'windows'
+  test_ddl_deparse_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'test_ddl_deparse',
+    '--FILEDESC', 'test_ddl_deparse - regression testing for DDL deparsing',])
+endif
+
 test_ddl_deparse = shared_module('test_ddl_deparse',
-  ['test_ddl_deparse.c'],
+  test_ddl_deparse_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += test_ddl_deparse
diff --git a/src/test/modules/test_ginpostinglist/meson.build b/src/test/modules/test_ginpostinglist/meson.build
index abf0a3b0430..b3b49c56122 100644
--- a/src/test/modules/test_ginpostinglist/meson.build
+++ b/src/test/modules/test_ginpostinglist/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+test_ginpostinglist_sources = files(
+  'test_ginpostinglist.c',
+)
+
+if host_system == 'windows'
+  test_ginpostinglist_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'test_ginpostinglist',
+    '--FILEDESC', 'test_ginpostinglist - test code for src/backend/access/gin//ginpostinglist.c',])
+endif
+
 test_ginpostinglist = shared_module('test_ginpostinglist',
-  ['test_ginpostinglist.c'],
+  test_ginpostinglist_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += test_ginpostinglist
diff --git a/src/test/modules/test_integerset/meson.build b/src/test/modules/test_integerset/meson.build
index c32c469c69a..4bd75af4b5e 100644
--- a/src/test/modules/test_integerset/meson.build
+++ b/src/test/modules/test_integerset/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+test_integerset_sources = files(
+  'test_integerset.c',
+)
+
+if host_system == 'windows'
+  test_integerset_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'test_integerset',
+    '--FILEDESC', 'test_integerset - test code for src/backend/lib/integerset.c',])
+endif
+
 test_integerset = shared_module('test_integerset',
-  ['test_integerset.c'],
+  test_integerset_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += test_integerset
diff --git a/src/test/modules/test_lfind/meson.build b/src/test/modules/test_lfind/meson.build
index a388de1156a..c5405b8f878 100644
--- a/src/test/modules/test_lfind/meson.build
+++ b/src/test/modules/test_lfind/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+test_lfind_sources = files(
+  'test_lfind.c',
+)
+
+if host_system == 'windows'
+  test_lfind_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'test_lfind',
+    '--FILEDESC', 'test_lfind - test code for optimized linear search functions',])
+endif
+
 test_lfind = shared_module('test_lfind',
-  ['test_lfind.c'],
+  test_lfind_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += test_lfind
diff --git a/src/test/modules/test_oat_hooks/meson.build b/src/test/modules/test_oat_hooks/meson.build
index 5faf0459777..8802bbbac55 100644
--- a/src/test/modules/test_oat_hooks/meson.build
+++ b/src/test/modules/test_oat_hooks/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+test_oat_hooks_sources = files(
+  'test_oat_hooks.c',
+)
+
+if host_system == 'windows'
+  test_oat_hooks_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'test_oat_hooks',
+    '--FILEDESC', 'test_oat_hooks - example use of object access hooks',])
+endif
+
 test_oat_hooks = shared_module('test_oat_hooks',
-  ['test_oat_hooks.c'],
+  test_oat_hooks_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += test_oat_hooks
diff --git a/src/test/modules/test_parser/meson.build b/src/test/modules/test_parser/meson.build
index b59960f615e..1c17113347f 100644
--- a/src/test/modules/test_parser/meson.build
+++ b/src/test/modules/test_parser/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+test_parser_sources = files(
+  'test_parser.c',
+)
+
+if host_system == 'windows'
+  test_parser_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'test_parser',
+    '--FILEDESC', 'test_parser - example of a custom parser for full-text search',])
+endif
+
 test_parser = shared_module('test_parser',
-  ['test_parser.c'],
+  test_parser_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += test_parser
diff --git a/src/test/modules/test_predtest/meson.build b/src/test/modules/test_predtest/meson.build
index 1cfa84b3609..9a5be43c9c0 100644
--- a/src/test/modules/test_predtest/meson.build
+++ b/src/test/modules/test_predtest/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+test_predtest_sources = files(
+  'test_predtest.c',
+)
+
+if host_system == 'windows'
+  test_predtest_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'test_predtest',
+    '--FILEDESC', 'test_predtest - test code for optimizer/util/predtest.c',])
+endif
+
 test_predtest = shared_module('test_predtest',
-  ['test_predtest.c'],
+  test_predtest_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += test_predtest
diff --git a/src/test/modules/test_rbtree/meson.build b/src/test/modules/test_rbtree/meson.build
index 34cbc3e1624..f067e08d321 100644
--- a/src/test/modules/test_rbtree/meson.build
+++ b/src/test/modules/test_rbtree/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+test_rbtree_sources = files(
+  'test_rbtree.c',
+)
+
+if host_system == 'windows'
+  test_rbtree_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'test_rbtree',
+    '--FILEDESC', 'test_rbtree - test code for red-black tree library',])
+endif
+
 test_rbtree = shared_module('test_rbtree',
-  ['test_rbtree.c'],
+  test_rbtree_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += test_rbtree
diff --git a/src/test/modules/test_regex/meson.build b/src/test/modules/test_regex/meson.build
index 867a64e57c3..cfb938d9f1e 100644
--- a/src/test/modules/test_regex/meson.build
+++ b/src/test/modules/test_regex/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+test_regex_sources = files(
+  'test_regex.c',
+)
+
+if host_system == 'windows'
+  test_regex_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'test_regex',
+    '--FILEDESC', 'test_regex - test code for backend/regex/',])
+endif
+
 test_regex = shared_module('test_regex',
-  ['test_regex.c'],
+  test_regex_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += test_regex
diff --git a/src/test/modules/test_rls_hooks/meson.build b/src/test/modules/test_rls_hooks/meson.build
index 80d8adda332..3fb273b2934 100644
--- a/src/test/modules/test_rls_hooks/meson.build
+++ b/src/test/modules/test_rls_hooks/meson.build
@@ -1,6 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+test_rls_hooks_sources = files(
+  'test_rls_hooks.c',
+)
+
+if host_system == 'windows'
+  test_rls_hooks_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'test_rls_hooks',
+    '--FILEDESC', 'test_rls_hooks - example use of RLS hooks',])
+endif
+
 test_rls_hooks = shared_module('test_rls_hooks',
-  ['test_rls_hooks.c'],
+  test_rls_hooks_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += test_rls_hooks
diff --git a/src/test/modules/test_shm_mq/meson.build b/src/test/modules/test_shm_mq/meson.build
index b663543d616..16c8fdb57f4 100644
--- a/src/test/modules/test_shm_mq/meson.build
+++ b/src/test/modules/test_shm_mq/meson.build
@@ -1,10 +1,19 @@
 # FIXME: prevent install during main install, but not during test :/
+
+test_shm_mq_sources = files(
+  'setup.c',
+  'test.c',
+  'worker.c',
+)
+
+if host_system == 'windows'
+  test_shm_mq_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'test_shm_mq',
+    '--FILEDESC', 'test_shm_mq - example use of shared memory message queue',])
+endif
+
 test_shm_mq = shared_module('test_shm_mq',
-  files(
-    'setup.c',
-    'test.c',
-    'worker.c',
-  ),
+  test_shm_mq_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += test_shm_mq
diff --git a/src/test/modules/worker_spi/meson.build b/src/test/modules/worker_spi/meson.build
index 32acad883b2..a4a158c75b9 100644
--- a/src/test/modules/worker_spi/meson.build
+++ b/src/test/modules/worker_spi/meson.build
@@ -1,8 +1,17 @@
 # FIXME: prevent install during main install, but not during test :/
+
+test_worker_spi_sources = files(
+  'worker_spi.c',
+)
+
+if host_system == 'windows'
+  test_worker_spi_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'worker_spi',
+    '--FILEDESC', 'worker_spi - background worker example',])
+endif
+
 test_worker_spi = shared_module('worker_spi',
-  files(
-    'worker_spi.c',
-  ),
+  test_worker_spi_sources,
   kwargs: pg_mod_args,
 )
 testprep_targets += test_worker_spi
diff --git a/src/test/regress/meson.build b/src/test/regress/meson.build
index 03de591b0c7..3dcfc11278f 100644
--- a/src/test/regress/meson.build
+++ b/src/test/regress/meson.build
@@ -17,6 +17,12 @@ host_tuple = '@0@-@1@-@2@'.format(host_cpu, host_system, host_tuple_cc)
 
 pg_regress_cflags = ['-DHOST_TUPLE="@0@"'.format(host_tuple), '-DSHELLPROG="/bin/sh"']
 
+if host_system == 'windows'
+  regress_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'pg_regress',
+    '--FILEDESC', 'pg_regress - test driver',])
+endif
+
 pg_regress = executable('pg_regress',
   regress_sources,
   c_args: pg_regress_cflags,
diff --git a/meson.build b/meson.build
index c709643fe5e..25a6fa941cc 100644
--- a/meson.build
+++ b/meson.build
@@ -2564,6 +2564,65 @@ gen_export_kwargs = {
 
 
 
+###
+### windows resources related stuff
+###
+
+if host_system == 'windows'
+  pg_ico = meson.source_root() / 'src' / 'port' / 'win32.ico'
+  win32ver_rc = files('src/port/win32ver.rc')
+  rcgen = find_program('src/tools/rcgen', native: true)
+
+  rcgen_base_args = [
+    '--srcdir', '@SOURCE_DIR@',
+    '--builddir', meson.build_root(),
+    '--rcout', '@OUTPUT0@',
+    '--out', '@OUTPUT1@',
+    '--input', '@INPUT@',
+    '@EXTRA_ARGS@',
+  ]
+
+  if cc.get_argument_syntax() == 'msvc'
+    rc = find_program('rc', required: true)
+    rcgen_base_args += ['--rc', rc.path()]
+    rcgen_outputs = ['@BASENAME@.rc', '@BASENAME@.res']
+  else
+    windres = find_program('windres', required: true)
+    rcgen_base_args += ['--windres', windres.path()]
+    rcgen_outputs = ['@BASENAME@.rc', '@BASENAME@.obj']
+  endif
+
+  # msbuild backend doesn't support this atm
+  if meson.backend() == 'ninja'
+    rcgen_base_args += ['--depfile', '@DEPFILE@']
+  endif
+
+  rcgen_bin_args = rcgen_base_args + [
+    '--VFT_TYPE', 'VFT_APP',
+    '--FILEENDING', 'exe',
+    '--ICO', pg_ico
+  ]
+
+  rcgen_lib_args = rcgen_base_args + [
+    '--VFT_TYPE', 'VFT_DLL',
+    '--FILEENDING', 'dll',
+  ]
+
+  rc_bin_gen = generator(rcgen,
+    depfile: '@BASENAME@.d',
+    arguments: rcgen_bin_args,
+    output: rcgen_outputs,
+  )
+
+  rc_lib_gen = generator(rcgen,
+    depfile: '@BASENAME@.d',
+    arguments: rcgen_lib_args,
+    output: rcgen_outputs,
+  )
+endif
+
+
+
 # headers that the whole build tree depends on
 generated_headers = []
 # headers that the backend build depends on
diff --git a/src/timezone/meson.build b/src/timezone/meson.build
index 16f082ecfa8..9e0934c000b 100644
--- a/src/timezone/meson.build
+++ b/src/timezone/meson.build
@@ -28,6 +28,12 @@ if get_option('system_tzdata') == ''
   if meson.is_cross_build()
     zic = find_program(get_option('ZIC'), native: true, required: true)
   else
+    if host_system == 'windows'
+      zic_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
+        '--NAME', 'zic',
+        '--FILEDESC', 'zic - time zone compiler',])
+    endif
+
     zic = executable('zic', zic_sources,
                      dependencies: [frontend_code],
                      kwargs: default_bin_args + {'install': false}
diff --git a/src/tools/rcgen b/src/tools/rcgen
new file mode 100755
index 00000000000..0c84772163c
--- /dev/null
+++ b/src/tools/rcgen
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+
+# Helper for building resource files when building for windows. Always
+# generates a .rc from the input .rc file. When building with msvc we
+# additionally generate a .res file with 'rc', when building with gcc, we use
+# windres to directly generate a .o.  Additionally we generate basic
+# dependencies if depfile is specified.
+
+import argparse
+import os
+import subprocess
+import sys
+
+parser = argparse.ArgumentParser(description='generate PostgreSQL rc file')
+
+parser.add_argument('--srcdir', type=os.path.abspath,
+                    required=True)
+parser.add_argument('--builddir', type=os.path.abspath,
+                    required=True)
+
+binaries = parser.add_argument_group('binaries')
+binaries.add_argument('--windres', type=os.path.abspath)
+binaries.add_argument('--rc', type=os.path.abspath)
+
+inout = parser.add_argument_group('inout')
+inout.add_argument('--depfile', type=argparse.FileType('w'))
+inout.add_argument('--input', type=argparse.FileType('r'),
+                   required=True)
+inout.add_argument('--rcout', type=argparse.FileType('w'),
+                   required=True)
+inout.add_argument('--out', type=str,
+                   required=True)
+
+replacements = parser.add_argument_group('replacements')
+replacements.add_argument('--FILEDESC', type=str)
+replacements.add_argument('--NAME', type=str, required=True)
+replacements.add_argument('--VFT_TYPE', type=str, required=True)
+replacements.add_argument('--FILEENDING', type=str, required=True)
+replacements.add_argument('--ICO', type=str)
+
+args = parser.parse_args()
+
+# determine replacement strings
+
+internal_name = '"{0}"'.format(args.NAME)
+original_name = '"{0}.{1}"'.format(args.NAME, args.FILEENDING)
+
+# if no description is passed in, generate one based on the name
+if args.FILEDESC:
+    filedesc = args.FILEDESC
+elif args.NAME:
+    if args.VFT_TYPE == 'VFT_DLL':
+        filedesc = 'PostgreSQL {0} library'.format(args.NAME)
+    else:
+        filedesc = 'PostgreSQL {0} binary'.format(args.NAME)
+filedesc = '"{0}"'.format(filedesc)
+
+
+if args.ICO:
+    ico = 'IDI_ICON ICON "{0}"'.format(args.ICO)
+    if args.depfile:
+        args.depfile.write("{0} : {1}\n".format(args.rcout.name, args.ICO))
+else:
+    ico = ''
+
+
+data = args.input.read()
+
+data = data.replace('VFT_APP', args.VFT_TYPE)
+data = data.replace('_INTERNAL_NAME_', internal_name)
+data = data.replace('_ORIGINAL_NAME_', original_name)
+data = data.replace('FILEDESC', filedesc)
+data = data.replace("_ICO_", ico)
+
+args.rcout.write(data)
+args.rcout.close()
+
+if args.windres:
+    cmd = [
+        args.windres,
+        '-I{0}/src/include/'.format(args.builddir),
+        '-I{0}/src/include/'.format(args.srcdir),
+        '-o', args.out, '-i', args.rcout.name,
+    ]
+elif args.rc:
+    cmd = [
+        args.rc, '/nologo',
+        '-I{0}/src/include/'.format(args.builddir),
+        '-I{0}/src/include/'.format(args.srcdir),
+        '/fo', args.out, args.rcout.name,
+    ]
+else:
+    sys.exit('either --windres or --rc needs to be specified')
+
+sp = subprocess.run(cmd)
+if sp.returncode != 0:
+    sys.exit(sp.returncode)
+
+# It'd be nicer if we could generate correct dependencies here, but 'rc'
+# doesn't support doing so. It's unlikely we'll ever need more, so...
+if args.depfile:
+    args.depfile.write("{0} : {1}\n".format(
+        args.rcout.name, args.input.name))
+    args.depfile.write("{0} : {1}/{2}\n".format(
+        args.out, args.builddir, 'src/include/pg_config.h'))
-- 
2.37.3.542.gdd3f6c4cae

Reply via email to