public inbox for [email protected]  
help / color / mirror / Atom feed
From: Zsolt Parragi <[email protected]>
To: PostgreSQL Hackers <[email protected]>
Subject: Proposal: common explicit lists for installed headers
Date: Sat, 14 Mar 2026 21:49:13 +0000
Message-ID: <CAN4CZFN=NaOVXmoPXpW11K93ZgZFUp_20BOU7Jj3vWJJepdfdQ@mail.gmail.com> (raw)

Hello

This patch is based on an idea in the recent headerscheck for meson
discussion[1]:
What if, instead of the current completely different ways we handle
installed headers in the make and meson builds, we used a common list
as the source of truth, explicitly listing all files that need to be
installed?

This has several advantages:

* removes the questionable install_subdir usage in meson
* removes the also questionable glob usage in make
* provides a clear list of includes we need in the installation directory
* this list could also later be used by headerscheck, which could then
work the same way in both meson and make

I have currently split this into three separate patches:

* the first one is the bulk of the changes, it handles everything in src/include
* the second adds the remaining src directories not included in the
first one. This is less useful for the unification goal, but it would
help with the headerscheck goal
* the third one is a completely optional unification. With the first
two patches, the public and internal headers are defined in two
separate lists because they come from different source directories.
This patch moves them into a single file instead, but with the
downside that the file now references headers in a different
directory. This is definitely questionable, I included it only as a
possible alternative, and ignoring it is probably better

What isn't included:

* contrib modules are unchanged - I didn't want to include them in a
common list, and adding separate list files per target would just add
complexity
* generated headers are similarly already listed explicitly in both
meson and make, I didn't change that

This could be a later question for headerscheck if we go in this
direction and want it to check these headers - but for now, manually
replicating them into lists doesn't seem practical.

I verified with a few different configurations that these changes
result in the same installed headers in both the make and meson builds
as before.

Thoughts? Would this be a useful refactoring?

[1]: https://www.postgresql.org/message-id/33wusv6jgyvm4tqw7ibjsh5vutnh3gyleyerkdzcv4mhf2ijmh%40wkirx27m6...


Attachments:

  [application/octet-stream] 0001-Unify-header-installation-using-shared-list-files.patch (30.1K, 2-0001-Unify-header-installation-using-shared-list-files.patch)
  download | inline diff:
From cf7db0a146391e1cf703fc024a2561f7664a26de Mon Sep 17 00:00:00 2001
From: Zsolt Parragi <[email protected]>
Date: Sat, 14 Mar 2026 11:07:36 +0000
Subject: [PATCH 1/3] Unify header installation using shared list files

Both make and meson builds now read the same list files
(public_headers.list, internal_headers.list, server_headers.list)
to determine which source-tree headers to install. This eliminates
the previous divergence where make used *.h globs and meson used
install_subdir(), and provides a single source of truth for installed
headers.

Generated headers remain handled explicitly by each build system.
The vpath_build conditional in catalog/Makefile is removed since the
parent Makefile no longer uses globs that would implicitly catch
generated headers in non-vpath builds.

Similarly contrib headers also remain as-is, as those are all explicitly
listed and unifying them into a single common list wouldn't align well
with the contrib concept.
---
 src/include/Makefile              |  84 +--
 src/include/catalog/Makefile      |   3 -
 src/include/internal_headers.list |  11 +
 src/include/meson.build           | 138 ++---
 src/include/public_headers.list   |  12 +
 src/include/server_headers.list   | 856 ++++++++++++++++++++++++++++++
 6 files changed, 936 insertions(+), 168 deletions(-)
 create mode 100644 src/include/internal_headers.list
 create mode 100644 src/include/public_headers.list
 create mode 100644 src/include/server_headers.list

diff --git a/src/include/Makefile b/src/include/Makefile
index ac673f4cf17..f2bed2578a5 100644
--- a/src/include/Makefile
+++ b/src/include/Makefile
@@ -12,94 +12,52 @@ subdir = src/include
 top_builddir = ../..
 include $(top_builddir)/src/Makefile.global
 
+PUBLIC_HEADERS := $(shell grep -v '^\#' $(srcdir)/public_headers.list | grep -v '^$$')
+INTERNAL_HEADERS := $(shell grep -v '^\#' $(srcdir)/internal_headers.list | grep -v '^$$')
+SERVER_HEADERS := $(shell grep -v '^\#' $(srcdir)/server_headers.list | grep -v '^$$')
 
 all: pg_config.h pg_config_os.h
 
 
-# Subdirectories containing installable headers
-SUBDIRS = \
-	access \
-	archive \
-	bootstrap \
-	catalog \
-	commands \
-	common \
-	datatype \
-	executor \
-	fe_utils \
-	foreign \
-	jit \
-	lib \
-	libpq \
-	mb \
-	nodes \
-	optimizer \
-	parser \
-	partitioning \
-	postmaster \
-	regex \
-	replication \
-	rewrite \
-	statistics \
-	storage \
-	tcop \
-	snowball \
-	snowball/libstemmer \
-	tsearch \
-	tsearch/dicts \
-	utils \
-	port \
-	port/atomics \
-	port/win32 \
-	port/win32_msvc \
-	port/win32_msvc/sys \
-	port/win32/arpa \
-	port/win32/netinet \
-	port/win32/sys \
-	portability
-
-# Install all headers
 install: all installdirs
 # These headers are needed by the public headers of the interfaces.
-	$(INSTALL_DATA) $(srcdir)/postgres_ext.h   '$(DESTDIR)$(includedir)'
-	$(INSTALL_DATA) $(srcdir)/libpq/libpq-fs.h '$(DESTDIR)$(includedir)/libpq'
+	for file in $(PUBLIC_HEADERS); do \
+	  $(INSTALL_DATA) $(srcdir)/$$file '$(DESTDIR)$(includedir)'/`dirname $$file` || exit; \
+	done
 	$(INSTALL_DATA) pg_config.h     '$(DESTDIR)$(includedir)'
 	$(INSTALL_DATA) pg_config_os.h  '$(DESTDIR)$(includedir)'
-	$(INSTALL_DATA) $(srcdir)/pg_config_manual.h '$(DESTDIR)$(includedir)'
 # These headers are needed by the not-so-public headers of the interfaces.
-	$(INSTALL_DATA) $(srcdir)/c.h            '$(DESTDIR)$(includedir_internal)'
-	$(INSTALL_DATA) $(srcdir)/port.h         '$(DESTDIR)$(includedir_internal)'
-	$(INSTALL_DATA) $(srcdir)/postgres_fe.h  '$(DESTDIR)$(includedir_internal)'
-	$(INSTALL_DATA) $(srcdir)/libpq/pqcomm.h '$(DESTDIR)$(includedir_internal)/libpq'
-	$(INSTALL_DATA) $(srcdir)/libpq/protocol.h '$(DESTDIR)$(includedir_internal)/libpq'
+	for file in $(INTERNAL_HEADERS); do \
+	  $(INSTALL_DATA) $(srcdir)/$$file '$(DESTDIR)$(includedir_internal)'/`dirname $$file` || exit; \
+	done
 # These headers are needed for server-side development
 	$(INSTALL_DATA) pg_config.h     '$(DESTDIR)$(includedir_server)'
 	$(INSTALL_DATA) pg_config_os.h  '$(DESTDIR)$(includedir_server)'
+	for file in $(SERVER_HEADERS); do \
+	  $(INSTALL_DATA) $(srcdir)/$$file '$(DESTDIR)$(includedir_server)'/`dirname $$file` || exit; \
+	done
+# Generated server headers (not in list files)
 	$(INSTALL_DATA) nodes/nodetags.h '$(DESTDIR)$(includedir_server)/nodes'
 	$(INSTALL_DATA) utils/errcodes.h '$(DESTDIR)$(includedir_server)/utils'
 	$(INSTALL_DATA) utils/fmgroids.h '$(DESTDIR)$(includedir_server)/utils'
 	$(INSTALL_DATA) utils/fmgrprotos.h '$(DESTDIR)$(includedir_server)/utils'
-	$(INSTALL_DATA) $(srcdir)/*.h '$(DESTDIR)$(includedir_server)'
-	for dir in $(SUBDIRS); do \
-	  $(INSTALL_DATA) $(srcdir)/$$dir/*.h '$(DESTDIR)$(includedir_server)'/$$dir || exit; \
-	done
-ifeq ($(vpath_build),yes)
 	for file in storage/lwlocknames.h utils/probes.h utils/wait_event_types.h; do \
 	  $(INSTALL_DATA) $$file '$(DESTDIR)$(includedir_server)'/$$file || exit; \
 	done
-endif
 	$(MAKE) -C catalog install
 
-installdirs:
-	$(MKDIR_P) '$(DESTDIR)$(includedir)/libpq' '$(DESTDIR)$(includedir_internal)/libpq'
-	$(MKDIR_P) $(addprefix '$(DESTDIR)$(includedir_server)'/, $(SUBDIRS))
+SERVER_HEADER_DIRS := $(sort $(patsubst %/,%,$(dir $(SERVER_HEADERS))))
 
+installdirs:
+	$(MKDIR_P) '$(DESTDIR)$(includedir)' $(addprefix '$(DESTDIR)$(includedir)'/, $(sort $(patsubst %/,%,$(filter-out ./,$(dir $(PUBLIC_HEADERS))))))
+	$(MKDIR_P) '$(DESTDIR)$(includedir_internal)' $(addprefix '$(DESTDIR)$(includedir_internal)'/, $(sort $(patsubst %/,%,$(filter-out ./,$(dir $(INTERNAL_HEADERS))))))
+	$(MKDIR_P) $(addprefix '$(DESTDIR)$(includedir_server)'/, $(SERVER_HEADER_DIRS))
 
 uninstall:
-	rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h)
-	rm -f $(addprefix '$(DESTDIR)$(includedir_internal)'/, c.h port.h postgres_fe.h libpq/pqcomm.h libpq/protocol.h)
+	rm -f $(addprefix '$(DESTDIR)$(includedir)'/, $(PUBLIC_HEADERS) pg_config.h pg_config_os.h)
+	rm -f $(addprefix '$(DESTDIR)$(includedir_internal)'/, $(INTERNAL_HEADERS))
 # heuristic...
-	rm -rf $(addprefix '$(DESTDIR)$(includedir_server)'/, $(SUBDIRS) *.h)
+	rm -rf $(addprefix '$(DESTDIR)$(includedir_server)'/, $(SERVER_HEADER_DIRS) *.h)
 	$(MAKE) -C catalog uninstall
 
 
diff --git a/src/include/catalog/Makefile b/src/include/catalog/Makefile
index 444fc76eed6..b8fa9df16b0 100644
--- a/src/include/catalog/Makefile
+++ b/src/include/catalog/Makefile
@@ -146,8 +146,6 @@ bki-stamp: $(top_srcdir)/src/backend/catalog/genbki.pl $(top_srcdir)/src/backend
 install: all installdirs
 	$(INSTALL_DATA) postgres.bki '$(DESTDIR)$(datadir)/postgres.bki'
 	$(INSTALL_DATA) system_constraints.sql '$(DESTDIR)$(datadir)/system_constraints.sql'
-# In non-vpath builds, src/include/Makefile already installs all headers.
-ifeq ($(vpath_build),yes)
 	$(INSTALL_DATA) schemapg.h '$(DESTDIR)$(includedir_server)'/catalog/schemapg.h
 	$(INSTALL_DATA) syscache_ids.h '$(DESTDIR)$(includedir_server)'/catalog/syscache_ids.h
 	$(INSTALL_DATA) syscache_info.h '$(DESTDIR)$(includedir_server)'/catalog/syscache_info.h
@@ -155,7 +153,6 @@ ifeq ($(vpath_build),yes)
 	for file in $(GENERATED_HEADERS); do \
 	  $(INSTALL_DATA) $$file '$(DESTDIR)$(includedir_server)'/catalog/$$file || exit; \
 	done
-endif
 
 installdirs:
 	$(MKDIR_P) '$(DESTDIR)$(datadir)' '$(DESTDIR)$(includedir_server)'
diff --git a/src/include/internal_headers.list b/src/include/internal_headers.list
new file mode 100644
index 00000000000..8e12f4d7cd6
--- /dev/null
+++ b/src/include/internal_headers.list
@@ -0,0 +1,11 @@
+# Internal client headers installed to $(includedir_internal)
+#
+# These headers are needed by the not-so-public headers of the interfaces,
+# i.e. for client library development.
+
+c.h
+port.h
+postgres_fe.h
+
+libpq/pqcomm.h
+libpq/protocol.h
diff --git a/src/include/meson.build b/src/include/meson.build
index 7d734d92dab..c03e508b961 100644
--- a/src/include/meson.build
+++ b/src/include/meson.build
@@ -72,51 +72,43 @@ pg_config_paths = configure_file(
 )
 configure_files += pg_config_paths
 
-install_headers(
-  'pg_config_manual.h',
-  'postgres_ext.h',
-)
-
-install_headers(
-  'libpq/libpq-fs.h',
-  install_dir: dir_include / 'libpq',
-)
-
-install_headers(
-  'c.h',
-  'port.h',
-  'postgres_fe.h',
-  install_dir: dir_include_internal,
-)
-
-install_headers(
-  'libpq/pqcomm.h',
-  'libpq/protocol.h',
-  install_dir: dir_include_internal / 'libpq',
-)
+_header_lists = {
+  'public_headers.list': dir_include,
+  'internal_headers.list': dir_include_internal,
+  'server_headers.list': dir_include_server,
+}
+
+foreach list_file, base_dir : _header_lists
+  prev_dir = ''
+  batch = []
+  foreach line : fs.read(list_file).strip().split('\n')
+    f = line.strip()
+    if f == '' or f.startswith('#')
+      continue
+    endif
+    d = fs.parent(f)
+    if d != prev_dir and batch.length() > 0
+      if prev_dir == '.'
+        install_headers(batch, install_dir: base_dir)
+      else
+        install_headers(batch, install_dir: base_dir / prev_dir)
+      endif
+      batch = []
+    endif
+    prev_dir = d
+    batch += f
+  endforeach
+  if batch.length() > 0
+    if prev_dir == '.'
+      install_headers(batch, install_dir: base_dir)
+    else
+      install_headers(batch, install_dir: base_dir / prev_dir)
+    endif
+  endif
+endforeach
 
-install_headers(
-  'c.h',
-  'fmgr.h',
-  'funcapi.h',
-  'getopt_long.h',
-  'miscadmin.h',
-  'pg_config_manual.h',
-  'pg_getopt.h',
-  'pg_trace.h',
-  'pgstat.h',
-  'pgtar.h',
-  'pgtime.h',
-  'port.h',
-  'postgres.h',
-  'postgres_ext.h',
-  'postgres_fe.h',
-  'varatt.h',
-  'windowapi.h',
-  pg_config_os,
-  pg_config,
-  install_dir: dir_include_server,
-)
+# Generated headers for server directory
+install_headers(pg_config_os, pg_config, install_dir: dir_include_server)
 
 subdir('catalog')
 subdir('nodes')
@@ -124,64 +116,6 @@ subdir('pch')
 subdir('storage')
 subdir('utils')
 
-header_subdirs = [
-  'access',
-  'archive',
-  'catalog',
-  'bootstrap',
-  'commands',
-  'common',
-  'datatype',
-  'executor',
-  'fe_utils',
-  'foreign',
-  'jit',
-  'lib',
-  'libpq',
-  'mb',
-  'nodes',
-  'optimizer',
-  'parser',
-  'partitioning',
-  'postmaster',
-  'regex',
-  'replication',
-  'rewrite',
-  'statistics',
-  'storage',
-  'tcop',
-  'snowball',
-  'tsearch',
-  'utils',
-  'port',
-  'portability',
-]
-
-# XXX: installing headers this way has the danger of installing editor files
-# etc, unfortunately install_subdir() doesn't allow including / excluding by
-# pattern currently.
-foreach d : header_subdirs
-  if d == 'catalog'
-    continue
-  endif
-  install_subdir(d, install_dir: dir_include_server,
-                 exclude_files: ['.gitignore', 'meson.build'])
-endforeach
-
-install_subdir('catalog',
-  install_dir: dir_include_server,
-  exclude_files: [
-    '.gitignore',
-    'Makefile',
-    'README',
-    'duplicate_oids',
-    'meson.build',
-    'reformat_dat_file.pl',
-    'renumber_oids.pl',
-    'unused_oids',
-  ] + bki_data,
-)
-
 # autoconf generates the file there, ensure we get a conflict
 generated_sources_ac += {'src/include': ['stamp-h']}
 
diff --git a/src/include/public_headers.list b/src/include/public_headers.list
new file mode 100644
index 00000000000..2cd1df6f8ab
--- /dev/null
+++ b/src/include/public_headers.list
@@ -0,0 +1,12 @@
+# Public API headers installed to $(includedir)
+#
+# These headers are needed by the public headers of the interfaces (e.g. libpq).
+# Generated headers are excluded from this list and handled directly by the
+# build system.
+#
+# Each source directory installs only the entries that exist locally.
+
+pg_config_manual.h
+postgres_ext.h
+
+libpq/libpq-fs.h
diff --git a/src/include/server_headers.list b/src/include/server_headers.list
new file mode 100644
index 00000000000..56d2e14d332
--- /dev/null
+++ b/src/include/server_headers.list
@@ -0,0 +1,856 @@
+# Server-side development headers installed to $(includedir_server)
+#
+# All source-tree headers needed for server-side development (e.g. extensions).
+# Generated headers are excluded from this list and handled directly by the
+# build system.
+
+c.h
+fmgr.h
+funcapi.h
+getopt_long.h
+miscadmin.h
+pg_config_manual.h
+pg_getopt.h
+pgstat.h
+pgtar.h
+pgtime.h
+pg_trace.h
+port.h
+postgres_ext.h
+postgres_fe.h
+postgres.h
+varatt.h
+windowapi.h
+
+access/amapi.h
+access/amvalidate.h
+access/attmap.h
+access/attnum.h
+access/brin.h
+access/brin_internal.h
+access/brin_page.h
+access/brin_pageops.h
+access/brin_revmap.h
+access/brin_tuple.h
+access/brin_xlog.h
+access/bufmask.h
+access/clog.h
+access/cmptype.h
+access/commit_ts.h
+access/detoast.h
+access/genam.h
+access/generic_xlog.h
+access/ginblock.h
+access/gin.h
+access/gin_private.h
+access/gin_tuple.h
+access/ginxlog.h
+access/gist.h
+access/gist_private.h
+access/gistscan.h
+access/gistxlog.h
+access/hash.h
+access/hash_xlog.h
+access/heapam.h
+access/heapam_xlog.h
+access/heaptoast.h
+access/hio.h
+access/htup_details.h
+access/htup.h
+access/itup.h
+access/multixact.h
+access/multixact_internal.h
+access/nbtree.h
+access/nbtxlog.h
+access/parallel.h
+access/printsimple.h
+access/printtup.h
+access/relation.h
+access/reloptions.h
+access/relscan.h
+access/rewriteheap.h
+access/rmgrdesc_utils.h
+access/rmgr.h
+access/rmgrlist.h
+access/sdir.h
+access/sequence.h
+access/session.h
+access/skey.h
+access/slru.h
+access/spgist.h
+access/spgist_private.h
+access/spgxlog.h
+access/stratnum.h
+access/subtrans.h
+access/syncscan.h
+access/sysattr.h
+access/tableam.h
+access/table.h
+access/tidstore.h
+access/timeline.h
+access/toast_compression.h
+access/toast_helper.h
+access/toast_internals.h
+access/transam.h
+access/tsmapi.h
+access/tupconvert.h
+access/tupdesc_details.h
+access/tupdesc.h
+access/tupmacs.h
+access/twophase.h
+access/twophase_rmgr.h
+access/valid.h
+access/visibilitymapdefs.h
+access/visibilitymap.h
+access/xact.h
+access/xlogarchive.h
+access/xlogbackup.h
+access/xlogdefs.h
+access/xlog.h
+access/xloginsert.h
+access/xlog_internal.h
+access/xlogprefetcher.h
+access/xlogreader.h
+access/xlogrecord.h
+access/xlogrecovery.h
+access/xlogstats.h
+access/xlogutils.h
+access/xlogwait.h
+
+archive/archive_module.h
+archive/shell_archive.h
+
+bootstrap/bootstrap.h
+
+catalog/binary_upgrade.h
+catalog/catalog.h
+catalog/catversion.h
+catalog/dependency.h
+catalog/genbki.h
+catalog/heap.h
+catalog/index.h
+catalog/indexing.h
+catalog/namespace.h
+catalog/objectaccess.h
+catalog/objectaddress.h
+catalog/partition.h
+catalog/pg_aggregate.h
+catalog/pg_am.h
+catalog/pg_amop.h
+catalog/pg_amproc.h
+catalog/pg_attrdef.h
+catalog/pg_attribute.h
+catalog/pg_authid.h
+catalog/pg_auth_members.h
+catalog/pg_cast.h
+catalog/pg_class.h
+catalog/pg_collation.h
+catalog/pg_constraint.h
+catalog/pg_control.h
+catalog/pg_conversion.h
+catalog/pg_database.h
+catalog/pg_db_role_setting.h
+catalog/pg_default_acl.h
+catalog/pg_depend.h
+catalog/pg_description.h
+catalog/pg_enum.h
+catalog/pg_event_trigger.h
+catalog/pg_extension.h
+catalog/pg_foreign_data_wrapper.h
+catalog/pg_foreign_server.h
+catalog/pg_foreign_table.h
+catalog/pg_index.h
+catalog/pg_inherits.h
+catalog/pg_init_privs.h
+catalog/pg_language.h
+catalog/pg_largeobject.h
+catalog/pg_largeobject_metadata.h
+catalog/pg_namespace.h
+catalog/pg_opclass.h
+catalog/pg_operator.h
+catalog/pg_opfamily.h
+catalog/pg_parameter_acl.h
+catalog/pg_partitioned_table.h
+catalog/pg_policy.h
+catalog/pg_proc.h
+catalog/pg_publication.h
+catalog/pg_publication_namespace.h
+catalog/pg_publication_rel.h
+catalog/pg_range.h
+catalog/pg_replication_origin.h
+catalog/pg_rewrite.h
+catalog/pg_seclabel.h
+catalog/pg_sequence.h
+catalog/pg_shdepend.h
+catalog/pg_shdescription.h
+catalog/pg_shseclabel.h
+catalog/pg_statistic_ext_data.h
+catalog/pg_statistic_ext.h
+catalog/pg_statistic.h
+catalog/pg_subscription.h
+catalog/pg_subscription_rel.h
+catalog/pg_tablespace.h
+catalog/pg_transform.h
+catalog/pg_trigger.h
+catalog/pg_ts_config.h
+catalog/pg_ts_config_map.h
+catalog/pg_ts_dict.h
+catalog/pg_ts_parser.h
+catalog/pg_ts_template.h
+catalog/pg_type.h
+catalog/pg_user_mapping.h
+catalog/storage.h
+catalog/storage_xlog.h
+catalog/toasting.h
+
+commands/alter.h
+commands/async.h
+commands/cluster.h
+commands/collationcmds.h
+commands/comment.h
+commands/conversioncmds.h
+commands/copyapi.h
+commands/copyfrom_internal.h
+commands/copy.h
+commands/createas.h
+commands/dbcommands.h
+commands/dbcommands_xlog.h
+commands/defrem.h
+commands/discard.h
+commands/event_trigger.h
+commands/explain_dr.h
+commands/explain_format.h
+commands/explain.h
+commands/explain_state.h
+commands/extension.h
+commands/lockcmds.h
+commands/matview.h
+commands/policy.h
+commands/portalcmds.h
+commands/prepare.h
+commands/proclang.h
+commands/progress.h
+commands/publicationcmds.h
+commands/schemacmds.h
+commands/seclabel.h
+commands/sequence.h
+commands/sequence_xlog.h
+commands/subscriptioncmds.h
+commands/tablecmds.h
+commands/tablespace.h
+commands/trigger.h
+commands/typecmds.h
+commands/user.h
+commands/vacuum.h
+commands/view.h
+commands/wait.h
+
+common/archive.h
+common/base64.h
+common/blkreftable.h
+common/checksum_helper.h
+common/compression.h
+common/config_info.h
+common/connect.h
+common/controldata_utils.h
+common/cryptohash.h
+common/fe_memutils.h
+common/file_perm.h
+common/file_utils.h
+common/hashfn.h
+common/hashfn_unstable.h
+common/hmac.h
+common/int128.h
+common/int.h
+common/ip.h
+common/jsonapi.h
+common/keywords.h
+common/kwlookup.h
+common/link-canary.h
+common/logging.h
+common/md5.h
+common/oauth-common.h
+common/openssl.h
+common/parse_manifest.h
+common/percentrepl.h
+common/pg_lzcompress.h
+common/pg_prng.h
+common/relpath.h
+common/restricted_token.h
+common/saslprep.h
+common/scram-common.h
+common/sha1.h
+common/sha2.h
+common/shortest_dec.h
+common/string.h
+common/unicode_case.h
+common/unicode_case_table.h
+common/unicode_category.h
+common/unicode_category_table.h
+common/unicode_east_asian_fw_table.h
+common/unicode_nonspacing_table.h
+common/unicode_norm.h
+common/unicode_norm_hashfunc.h
+common/unicode_normprops_table.h
+common/unicode_norm_table.h
+common/unicode_version.h
+common/username.h
+
+datatype/timestamp.h
+
+executor/execAsync.h
+executor/execdebug.h
+executor/execdesc.h
+executor/execExpr.h
+executor/execParallel.h
+executor/execPartition.h
+executor/execScan.h
+executor/executor.h
+executor/functions.h
+executor/hashjoin.h
+executor/instrument.h
+executor/instrument_node.h
+executor/nodeAgg.h
+executor/nodeAppend.h
+executor/nodeBitmapAnd.h
+executor/nodeBitmapHeapscan.h
+executor/nodeBitmapIndexscan.h
+executor/nodeBitmapOr.h
+executor/nodeCtescan.h
+executor/nodeCustom.h
+executor/nodeForeignscan.h
+executor/nodeFunctionscan.h
+executor/nodeGather.h
+executor/nodeGatherMerge.h
+executor/nodeGroup.h
+executor/nodeHash.h
+executor/nodeHashjoin.h
+executor/nodeIncrementalSort.h
+executor/nodeIndexonlyscan.h
+executor/nodeIndexscan.h
+executor/nodeLimit.h
+executor/nodeLockRows.h
+executor/nodeMaterial.h
+executor/nodeMemoize.h
+executor/nodeMergeAppend.h
+executor/nodeMergejoin.h
+executor/nodeModifyTable.h
+executor/nodeNamedtuplestorescan.h
+executor/nodeNestloop.h
+executor/nodeProjectSet.h
+executor/nodeRecursiveunion.h
+executor/nodeResult.h
+executor/nodeSamplescan.h
+executor/nodeSeqscan.h
+executor/nodeSetOp.h
+executor/nodeSort.h
+executor/nodeSubplan.h
+executor/nodeSubqueryscan.h
+executor/nodeTableFuncscan.h
+executor/nodeTidrangescan.h
+executor/nodeTidscan.h
+executor/nodeUnique.h
+executor/nodeValuesscan.h
+executor/nodeWindowAgg.h
+executor/nodeWorktablescan.h
+executor/spi.h
+executor/spi_priv.h
+executor/tablefunc.h
+executor/tqueue.h
+executor/tstoreReceiver.h
+executor/tuptable.h
+
+fe_utils/archive.h
+fe_utils/astreamer.h
+fe_utils/cancel.h
+fe_utils/conditional.h
+fe_utils/connect_utils.h
+fe_utils/mbprint.h
+fe_utils/option_utils.h
+fe_utils/parallel_slot.h
+fe_utils/print.h
+fe_utils/psqlscan.h
+fe_utils/psqlscan_int.h
+fe_utils/query_utils.h
+fe_utils/recovery_gen.h
+fe_utils/simple_list.h
+fe_utils/string_utils.h
+fe_utils/version.h
+
+foreign/fdwapi.h
+foreign/foreign.h
+
+jit/jit.h
+jit/llvmjit_backport.h
+jit/llvmjit_emit.h
+jit/llvmjit.h
+jit/SectionMemoryManager.h
+
+lib/binaryheap.h
+lib/bipartite_match.h
+lib/bloomfilter.h
+lib/dshash.h
+lib/hyperloglog.h
+lib/ilist.h
+lib/integerset.h
+lib/knapsack.h
+lib/pairingheap.h
+lib/qunique.h
+lib/radixtree.h
+lib/rbtree.h
+lib/simplehash.h
+lib/sort_template.h
+lib/stringinfo.h
+
+libpq/auth.h
+libpq/be-fsstubs.h
+libpq/be-gssapi-common.h
+libpq/crypt.h
+libpq/hba.h
+libpq/ifaddr.h
+libpq/libpq-be-fe.h
+libpq/libpq-be-fe-helpers.h
+libpq/libpq-be.h
+libpq/libpq-fs.h
+libpq/libpq.h
+libpq/oauth.h
+libpq/pg-gssapi.h
+libpq/pqcomm.h
+libpq/pqformat.h
+libpq/pqmq.h
+libpq/pqsignal.h
+libpq/protocol.h
+libpq/sasl.h
+libpq/scram.h
+
+mb/pg_wchar.h
+mb/stringinfo_mb.h
+
+nodes/bitmapset.h
+nodes/execnodes.h
+nodes/extensible.h
+nodes/lockoptions.h
+nodes/makefuncs.h
+nodes/memnodes.h
+nodes/miscnodes.h
+nodes/multibitmapset.h
+nodes/nodeFuncs.h
+nodes/nodes.h
+nodes/params.h
+nodes/parsenodes.h
+nodes/pathnodes.h
+nodes/pg_list.h
+nodes/plannodes.h
+nodes/primnodes.h
+nodes/print.h
+nodes/queryjumble.h
+nodes/readfuncs.h
+nodes/replnodes.h
+nodes/subscripting.h
+nodes/supportnodes.h
+nodes/tidbitmap.h
+nodes/value.h
+
+optimizer/appendinfo.h
+optimizer/clauses.h
+optimizer/cost.h
+optimizer/extendplan.h
+optimizer/geqo_copy.h
+optimizer/geqo_gene.h
+optimizer/geqo.h
+optimizer/geqo_misc.h
+optimizer/geqo_mutation.h
+optimizer/geqo_pool.h
+optimizer/geqo_random.h
+optimizer/geqo_recombination.h
+optimizer/geqo_selection.h
+optimizer/inherit.h
+optimizer/joininfo.h
+optimizer/optimizer.h
+optimizer/orclauses.h
+optimizer/paramassign.h
+optimizer/pathnode.h
+optimizer/paths.h
+optimizer/placeholder.h
+optimizer/plancat.h
+optimizer/planmain.h
+optimizer/planner.h
+optimizer/prep.h
+optimizer/restrictinfo.h
+optimizer/subselect.h
+optimizer/tlist.h
+
+parser/analyze.h
+parser/kwlist.h
+parser/parse_agg.h
+parser/parse_clause.h
+parser/parse_coerce.h
+parser/parse_collate.h
+parser/parse_cte.h
+parser/parse_enr.h
+parser/parse_expr.h
+parser/parse_func.h
+parser/parse_merge.h
+parser/parse_node.h
+parser/parse_oper.h
+parser/parse_param.h
+parser/parse_relation.h
+parser/parser.h
+parser/parse_target.h
+parser/parsetree.h
+parser/parse_type.h
+parser/parse_utilcmd.h
+parser/scanner.h
+parser/scansup.h
+
+partitioning/partbounds.h
+partitioning/partdefs.h
+partitioning/partdesc.h
+partitioning/partprune.h
+
+portability/instr_time.h
+portability/mem.h
+
+port/aix.h
+port/atomics/arch-arm.h
+port/atomics/arch-ppc.h
+port/atomics/arch-x86.h
+port/atomics/fallback.h
+port/atomics/generic-gcc.h
+port/atomics/generic.h
+port/atomics/generic-msvc.h
+port/atomics.h
+port/cygwin.h
+port/darwin.h
+port/freebsd.h
+port/linux.h
+port/netbsd.h
+port/openbsd.h
+port/pg_bitutils.h
+port/pg_bswap.h
+port/pg_cpu.h
+port/pg_crc32c.h
+port/pg_iovec.h
+port/pg_lfind.h
+port/pg_numa.h
+port/pg_pthread.h
+port/simd.h
+port/solaris.h
+port/win32/arpa/inet.h
+port/win32/dlfcn.h
+port/win32/grp.h
+port/win32.h
+port/win32_msvc/dirent.h
+port/win32_msvc/sys/file.h
+port/win32_msvc/sys/param.h
+port/win32_msvc/sys/time.h
+port/win32_msvc/unistd.h
+port/win32_msvc/utime.h
+port/win32/netdb.h
+port/win32/netinet/in.h
+port/win32/netinet/tcp.h
+port/win32ntdll.h
+port/win32_port.h
+port/win32/pwd.h
+port/win32/sys/resource.h
+port/win32/sys/select.h
+port/win32/sys/socket.h
+port/win32/sys/un.h
+port/win32/sys/wait.h
+
+postmaster/autovacuum.h
+postmaster/auxprocess.h
+postmaster/bgworker.h
+postmaster/bgworker_internals.h
+postmaster/bgwriter.h
+postmaster/fork_process.h
+postmaster/interrupt.h
+postmaster/pgarch.h
+postmaster/postmaster.h
+postmaster/proctypelist.h
+postmaster/startup.h
+postmaster/syslogger.h
+postmaster/walsummarizer.h
+postmaster/walwriter.h
+
+regex/regcustom.h
+regex/regerrs.h
+regex/regex.h
+regex/regexport.h
+regex/regguts.h
+
+replication/conflict.h
+replication/decode.h
+replication/logicalctl.h
+replication/logical.h
+replication/logicallauncher.h
+replication/logicalproto.h
+replication/logicalrelation.h
+replication/logicalworker.h
+replication/message.h
+replication/origin.h
+replication/output_plugin.h
+replication/pgoutput.h
+replication/reorderbuffer.h
+replication/slot.h
+replication/slotsync.h
+replication/snapbuild.h
+replication/snapbuild_internal.h
+replication/syncrep.h
+replication/walreceiver.h
+replication/walsender.h
+replication/walsender_private.h
+replication/worker_internal.h
+
+rewrite/prs2lock.h
+rewrite/rewriteDefine.h
+rewrite/rewriteHandler.h
+rewrite/rewriteManip.h
+rewrite/rewriteRemove.h
+rewrite/rewriteSearchCycle.h
+rewrite/rewriteSupport.h
+rewrite/rowsecurity.h
+
+snowball/libstemmer/api.h
+snowball/libstemmer/snowball_runtime.h
+snowball/libstemmer/stem_ISO_8859_1_basque.h
+snowball/libstemmer/stem_ISO_8859_1_catalan.h
+snowball/libstemmer/stem_ISO_8859_1_danish.h
+snowball/libstemmer/stem_ISO_8859_1_dutch.h
+snowball/libstemmer/stem_ISO_8859_1_dutch_porter.h
+snowball/libstemmer/stem_ISO_8859_1_english.h
+snowball/libstemmer/stem_ISO_8859_1_finnish.h
+snowball/libstemmer/stem_ISO_8859_1_french.h
+snowball/libstemmer/stem_ISO_8859_1_german.h
+snowball/libstemmer/stem_ISO_8859_1_indonesian.h
+snowball/libstemmer/stem_ISO_8859_1_irish.h
+snowball/libstemmer/stem_ISO_8859_1_italian.h
+snowball/libstemmer/stem_ISO_8859_1_norwegian.h
+snowball/libstemmer/stem_ISO_8859_1_porter.h
+snowball/libstemmer/stem_ISO_8859_1_portuguese.h
+snowball/libstemmer/stem_ISO_8859_1_spanish.h
+snowball/libstemmer/stem_ISO_8859_1_swedish.h
+snowball/libstemmer/stem_ISO_8859_2_hungarian.h
+snowball/libstemmer/stem_ISO_8859_2_polish.h
+snowball/libstemmer/stem_KOI8_R_russian.h
+snowball/libstemmer/stem_UTF_8_arabic.h
+snowball/libstemmer/stem_UTF_8_armenian.h
+snowball/libstemmer/stem_UTF_8_basque.h
+snowball/libstemmer/stem_UTF_8_catalan.h
+snowball/libstemmer/stem_UTF_8_danish.h
+snowball/libstemmer/stem_UTF_8_dutch.h
+snowball/libstemmer/stem_UTF_8_dutch_porter.h
+snowball/libstemmer/stem_UTF_8_english.h
+snowball/libstemmer/stem_UTF_8_esperanto.h
+snowball/libstemmer/stem_UTF_8_estonian.h
+snowball/libstemmer/stem_UTF_8_finnish.h
+snowball/libstemmer/stem_UTF_8_french.h
+snowball/libstemmer/stem_UTF_8_german.h
+snowball/libstemmer/stem_UTF_8_greek.h
+snowball/libstemmer/stem_UTF_8_hindi.h
+snowball/libstemmer/stem_UTF_8_hungarian.h
+snowball/libstemmer/stem_UTF_8_indonesian.h
+snowball/libstemmer/stem_UTF_8_irish.h
+snowball/libstemmer/stem_UTF_8_italian.h
+snowball/libstemmer/stem_UTF_8_lithuanian.h
+snowball/libstemmer/stem_UTF_8_nepali.h
+snowball/libstemmer/stem_UTF_8_norwegian.h
+snowball/libstemmer/stem_UTF_8_polish.h
+snowball/libstemmer/stem_UTF_8_porter.h
+snowball/libstemmer/stem_UTF_8_portuguese.h
+snowball/libstemmer/stem_UTF_8_romanian.h
+snowball/libstemmer/stem_UTF_8_russian.h
+snowball/libstemmer/stem_UTF_8_serbian.h
+snowball/libstemmer/stem_UTF_8_spanish.h
+snowball/libstemmer/stem_UTF_8_swedish.h
+snowball/libstemmer/stem_UTF_8_tamil.h
+snowball/libstemmer/stem_UTF_8_turkish.h
+snowball/libstemmer/stem_UTF_8_yiddish.h
+snowball/snowball_runtime.h
+
+statistics/extended_stats_internal.h
+statistics/statistics_format.h
+statistics/statistics.h
+statistics/stat_utils.h
+
+storage/aio.h
+storage/aio_internal.h
+storage/aio_subsys.h
+storage/aio_types.h
+storage/barrier.h
+storage/block.h
+storage/buffile.h
+storage/buf.h
+storage/buf_internals.h
+storage/bufmgr.h
+storage/bufpage.h
+storage/bulk_write.h
+storage/checksum.h
+storage/checksum_impl.h
+storage/condition_variable.h
+storage/copydir.h
+storage/dsm.h
+storage/dsm_impl.h
+storage/dsm_registry.h
+storage/fd.h
+storage/fileset.h
+storage/freespace.h
+storage/fsm_internals.h
+storage/indexfsm.h
+storage/io_worker.h
+storage/ipc.h
+storage/itemid.h
+storage/itemptr.h
+storage/large_object.h
+storage/latch.h
+storage/lmgr.h
+storage/lockdefs.h
+storage/lock.h
+storage/lwlock.h
+storage/lwlocklist.h
+storage/md.h
+storage/off.h
+storage/pg_sema.h
+storage/pg_shmem.h
+storage/pmsignal.h
+storage/predicate.h
+storage/predicate_internals.h
+storage/procarray.h
+storage/proc.h
+storage/proclist.h
+storage/proclist_types.h
+storage/procnumber.h
+storage/procsignal.h
+storage/read_stream.h
+storage/reinit.h
+storage/relfilelocator.h
+storage/sharedfileset.h
+storage/shmem.h
+storage/shm_mq.h
+storage/shm_toc.h
+storage/sinvaladt.h
+storage/sinval.h
+storage/s_lock.h
+storage/smgr.h
+storage/spin.h
+storage/standbydefs.h
+storage/standby.h
+storage/sync.h
+storage/waiteventset.h
+
+tcop/backend_startup.h
+tcop/cmdtag.h
+tcop/cmdtaglist.h
+tcop/deparse_utility.h
+tcop/dest.h
+tcop/fastpath.h
+tcop/pquery.h
+tcop/tcopprot.h
+tcop/utility.h
+
+tsearch/dicts/regis.h
+tsearch/dicts/spell.h
+tsearch/ts_cache.h
+tsearch/ts_locale.h
+tsearch/ts_public.h
+tsearch/ts_type.h
+tsearch/ts_utils.h
+
+utils/aclchk_internal.h
+utils/acl.h
+utils/arrayaccess.h
+utils/array.h
+utils/ascii.h
+utils/attoptcache.h
+utils/backend_progress.h
+utils/backend_status.h
+utils/builtins.h
+utils/bytea.h
+utils/cash.h
+utils/catcache.h
+utils/combocid.h
+utils/conffiles.h
+utils/date.h
+utils/datetime.h
+utils/datum.h
+utils/dsa.h
+utils/elog.h
+utils/evtcache.h
+utils/expandeddatum.h
+utils/expandedrecord.h
+utils/float.h
+utils/fmgrtab.h
+utils/formatting.h
+utils/freepage.h
+utils/funccache.h
+utils/geo_decls.h
+utils/guc.h
+utils/guc_hooks.h
+utils/guc_tables.h
+utils/help_config.h
+utils/hsearch.h
+utils/index_selfuncs.h
+utils/inet.h
+utils/injection_point.h
+utils/inval.h
+utils/jsonb.h
+utils/jsonfuncs.h
+utils/json.h
+utils/jsonpath.h
+utils/logtape.h
+utils/lsyscache.h
+utils/memdebug.h
+utils/memutils.h
+utils/memutils_internal.h
+utils/memutils_memorychunk.h
+utils/multirangetypes.h
+utils/numeric.h
+utils/palloc.h
+utils/partcache.h
+utils/pg_crc.h
+utils/pg_locale_c.h
+utils/pg_locale.h
+utils/pg_lsn.h
+utils/pg_rusage.h
+utils/pgstat_internal.h
+utils/pgstat_kind.h
+utils/pidfile.h
+utils/plancache.h
+utils/portal.h
+utils/ps_status.h
+utils/queryenvironment.h
+utils/rangetypes.h
+utils/regproc.h
+utils/relcache.h
+utils/relfilenumbermap.h
+utils/rel.h
+utils/relmapper.h
+utils/relptr.h
+utils/reltrigger.h
+utils/resowner.h
+utils/rls.h
+utils/ruleutils.h
+utils/sampling.h
+utils/selfuncs.h
+utils/sharedtuplestore.h
+utils/skipsupport.h
+utils/snapmgr.h
+utils/snapshot.h
+utils/sortsupport.h
+utils/spccache.h
+utils/syscache.h
+utils/timeout.h
+utils/timestamp.h
+utils/tuplesort.h
+utils/tuplestore.h
+utils/typcache.h
+utils/tzparser.h
+utils/usercontext.h
+utils/uuid.h
+utils/varbit.h
+utils/varlena.h
+utils/wait_classes.h
+utils/wait_event.h
+utils/xid8.h
+utils/xml.h
+
-- 
2.43.0



  [application/octet-stream] 0002-Extend-header-list-files-to-libpq-ecpg-and-PL-langua.patch (15.0K, 3-0002-Extend-header-list-files-to-libpq-ecpg-and-PL-langua.patch)
  download | inline diff:
From c8794fa84b4a200841ccafe274378f1cd578c8f6 Mon Sep 17 00:00:00 2001
From: Zsolt Parragi <[email protected]>
Date: Sat, 14 Mar 2026 15:10:45 +0000
Subject: [PATCH 2/3] Extend header list files to libpq, ecpg, and PL languages

Apply the same shared-list-file approach from src/include/ to
all other src/ directories that install headers: libpq, ecpg,
plpgsql, plperl, and plpython. Each directory now has its own
list file(s) that both make and meson read, eliminating duplicate
header lists in the two build systems.
---
 src/interfaces/ecpg/include/Makefile          |  6 +--
 .../ecpg/include/informix_headers.list        |  4 ++
 src/interfaces/ecpg/include/meson.build       | 39 ++++++++-----------
 .../ecpg/include/public_headers.list          | 17 ++++++++
 src/interfaces/libpq/Makefile                 | 17 ++++----
 src/interfaces/libpq/internal_headers.list    |  4 ++
 src/interfaces/libpq/meson.build              | 28 +++++++------
 src/interfaces/libpq/public_headers.list      |  3 ++
 src/pl/plperl/GNUmakefile                     |  6 ++-
 src/pl/plperl/install_headers.list            |  4 ++
 src/pl/plperl/meson.build                     | 14 ++++---
 src/pl/plpgsql/src/Makefile                   |  7 ++--
 src/pl/plpgsql/src/install_headers.list       |  2 +
 src/pl/plpgsql/src/meson.build                | 12 ++++--
 src/pl/plpython/Makefile                      | 17 +-------
 src/pl/plpython/install_headers.list          | 15 +++++++
 src/pl/plpython/meson.build                   | 25 ++++--------
 17 files changed, 125 insertions(+), 95 deletions(-)
 create mode 100644 src/interfaces/ecpg/include/informix_headers.list
 create mode 100644 src/interfaces/ecpg/include/public_headers.list
 create mode 100644 src/interfaces/libpq/internal_headers.list
 create mode 100644 src/interfaces/libpq/public_headers.list
 create mode 100644 src/pl/plperl/install_headers.list
 create mode 100644 src/pl/plpgsql/src/install_headers.list
 create mode 100644 src/pl/plpython/install_headers.list

diff --git a/src/interfaces/ecpg/include/Makefile b/src/interfaces/ecpg/include/Makefile
index 3476409cefb..e2d7ece3392 100644
--- a/src/interfaces/ecpg/include/Makefile
+++ b/src/interfaces/ecpg/include/Makefile
@@ -13,10 +13,8 @@ all: $(ecpg_config_h)
 install: all installdirs install-headers
 
 .PHONY: install-headers
-ecpg_headers = ecpgerrno.h ecpglib.h ecpgtype.h sqlca.h sql3types.h ecpg_informix.h \
-	pgtypes_error.h pgtypes_numeric.h pgtypes_timestamp.h pgtypes_date.h pgtypes_interval.h pgtypes.h \
-	sqlda.h sqlda-compat.h sqlda-native.h
-informix_headers = datetime.h decimal.h sqltypes.h
+ecpg_headers := $(shell grep -v '^\#' $(srcdir)/public_headers.list | grep -v '^$$')
+informix_headers := $(shell grep -v '^\#' $(srcdir)/informix_headers.list | grep -v '^$$')
 
 install-headers: $(ecpg_headers) $(informix_headers) installdirs
 	$(INSTALL_DATA) $(addprefix $(srcdir)/,$(ecpg_headers)) '$(DESTDIR)$(includedir)/'
diff --git a/src/interfaces/ecpg/include/informix_headers.list b/src/interfaces/ecpg/include/informix_headers.list
new file mode 100644
index 00000000000..47fb1ea552f
--- /dev/null
+++ b/src/interfaces/ecpg/include/informix_headers.list
@@ -0,0 +1,4 @@
+# Informix compatibility headers installed to $(pkgincludedir)/informix/esql
+datetime.h
+decimal.h
+sqltypes.h
diff --git a/src/interfaces/ecpg/include/meson.build b/src/interfaces/ecpg/include/meson.build
index a34a4e30f38..4ddcd1bb739 100644
--- a/src/interfaces/ecpg/include/meson.build
+++ b/src/interfaces/ecpg/include/meson.build
@@ -26,27 +26,20 @@ configure_files += ecpg_config_h
 
 generated_sources_ac += {'src/interfaces/ecpg/include': ['stamp-h']}
 
-install_headers(
-  'ecpg_informix.h',
-  'ecpgerrno.h',
-  'ecpglib.h',
-  'ecpgtype.h',
-  'pgtypes.h',
-  'pgtypes_date.h',
-  'pgtypes_error.h',
-  'pgtypes_interval.h',
-  'pgtypes_numeric.h',
-  'pgtypes_timestamp.h',
-  'sql3types.h',
-  'sqlca.h',
-  'sqlda.h',
-  'sqlda-compat.h',
-  'sqlda-native.h',
-)
+_h = []
+foreach l : fs.read('public_headers.list').strip().split('\n')
+  l = l.strip()
+  if l != '' and not l.startswith('#')
+    _h += l
+  endif
+endforeach
+install_headers(_h)
 
-install_headers(
-  'datetime.h',
-  'decimal.h',
-  'sqltypes.h',
-  install_dir: dir_include_pkg / 'informix' / 'esql',
-)
+_h = []
+foreach l : fs.read('informix_headers.list').strip().split('\n')
+  l = l.strip()
+  if l != '' and not l.startswith('#')
+    _h += l
+  endif
+endforeach
+install_headers(_h, install_dir: dir_include_pkg / 'informix' / 'esql')
diff --git a/src/interfaces/ecpg/include/public_headers.list b/src/interfaces/ecpg/include/public_headers.list
new file mode 100644
index 00000000000..8adc7e6dff5
--- /dev/null
+++ b/src/interfaces/ecpg/include/public_headers.list
@@ -0,0 +1,17 @@
+# Public ecpg headers installed to $(includedir)
+# Generated header ecpg_config.h is not listed here.
+ecpg_informix.h
+ecpgerrno.h
+ecpglib.h
+ecpgtype.h
+pgtypes.h
+pgtypes_date.h
+pgtypes_error.h
+pgtypes_interval.h
+pgtypes_numeric.h
+pgtypes_timestamp.h
+sql3types.h
+sqlca.h
+sqlda-compat.h
+sqlda-native.h
+sqlda.h
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index 0963995eed4..b9319fab869 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -15,6 +15,9 @@ subdir = src/interfaces/libpq
 top_builddir = ../../..
 include $(top_builddir)/src/Makefile.global
 
+PUBLIC_HEADERS := $(shell grep -v '^\#' $(srcdir)/public_headers.list | grep -v '^$$')
+INTERNAL_HEADERS := $(shell grep -v '^\#' $(srcdir)/internal_headers.list | grep -v '^$$')
+
 export with_ssl with_gssapi with_krb_srvnam
 
 PGFILEDESC = "PostgreSQL Access Library"
@@ -155,11 +158,8 @@ $(top_builddir)/src/port/pg_config_paths.h:
 	$(CC) $(CFLAGS) $(CFLAGS_SL) $(CPPFLAGS) $(CPPFLAGS_SHLIB) -c $< -o $@
 
 install: all installdirs install-lib
-	$(INSTALL_DATA) $(srcdir)/libpq-fe.h '$(DESTDIR)$(includedir)'
-	$(INSTALL_DATA) $(srcdir)/libpq-events.h '$(DESTDIR)$(includedir)'
-	$(INSTALL_DATA) $(srcdir)/libpq-int.h '$(DESTDIR)$(includedir_internal)'
-	$(INSTALL_DATA) $(srcdir)/fe-auth-sasl.h '$(DESTDIR)$(includedir_internal)'
-	$(INSTALL_DATA) $(srcdir)/pqexpbuffer.h '$(DESTDIR)$(includedir_internal)'
+	$(INSTALL_DATA) $(addprefix $(srcdir)/,$(PUBLIC_HEADERS)) '$(DESTDIR)$(includedir)'
+	$(INSTALL_DATA) $(addprefix $(srcdir)/,$(INTERNAL_HEADERS)) '$(DESTDIR)$(includedir_internal)'
 	$(INSTALL_DATA) $(srcdir)/pg_service.conf.sample '$(DESTDIR)$(datadir)/pg_service.conf.sample'
 
 test-build:
@@ -177,11 +177,8 @@ installdirs: installdirs-lib
 	$(MKDIR_P) '$(DESTDIR)$(includedir)' '$(DESTDIR)$(includedir_internal)' '$(DESTDIR)$(datadir)'
 
 uninstall: uninstall-lib
-	rm -f '$(DESTDIR)$(includedir)/libpq-fe.h'
-	rm -f '$(DESTDIR)$(includedir)/libpq-events.h'
-	rm -f '$(DESTDIR)$(includedir_internal)/libpq-int.h'
-	rm -f '$(DESTDIR)$(includedir_internal)/fe-auth-sasl.h'
-	rm -f '$(DESTDIR)$(includedir_internal)/pqexpbuffer.h'
+	rm -f $(addprefix '$(DESTDIR)$(includedir)'/, $(PUBLIC_HEADERS))
+	rm -f $(addprefix '$(DESTDIR)$(includedir_internal)'/, $(INTERNAL_HEADERS))
 	rm -f '$(DESTDIR)$(datadir)/pg_service.conf.sample'
 
 clean distclean: clean-lib
diff --git a/src/interfaces/libpq/internal_headers.list b/src/interfaces/libpq/internal_headers.list
new file mode 100644
index 00000000000..635f735b0ad
--- /dev/null
+++ b/src/interfaces/libpq/internal_headers.list
@@ -0,0 +1,4 @@
+# Internal libpq headers installed to $(includedir_internal)
+fe-auth-sasl.h
+libpq-int.h
+pqexpbuffer.h
diff --git a/src/interfaces/libpq/meson.build b/src/interfaces/libpq/meson.build
index b0ae72167a1..09f7f8c85c0 100644
--- a/src/interfaces/libpq/meson.build
+++ b/src/interfaces/libpq/meson.build
@@ -132,17 +132,23 @@ pkgconfig.generate(
   libraries_private: private_deps,
 )
 
-install_headers(
-  'libpq-fe.h',
-  'libpq-events.h',
-)
-
-install_headers(
-  'libpq-int.h',
-  'pqexpbuffer.h',
-  'fe-auth-sasl.h',
-  install_dir: dir_include_internal,
-)
+_h = []
+foreach l : fs.read('public_headers.list').strip().split('\n')
+  l = l.strip()
+  if l != '' and not l.startswith('#')
+    _h += l
+  endif
+endforeach
+install_headers(_h)
+
+_h = []
+foreach l : fs.read('internal_headers.list').strip().split('\n')
+  l = l.strip()
+  if l != '' and not l.startswith('#')
+    _h += l
+  endif
+endforeach
+install_headers(_h, install_dir: dir_include_internal)
 install_data('pg_service.conf.sample',
   install_dir: dir_data,
 )
diff --git a/src/interfaces/libpq/public_headers.list b/src/interfaces/libpq/public_headers.list
new file mode 100644
index 00000000000..26dbe72b8ea
--- /dev/null
+++ b/src/interfaces/libpq/public_headers.list
@@ -0,0 +1,3 @@
+# Public libpq headers installed to $(includedir)
+libpq-events.h
+libpq-fe.h
diff --git a/src/pl/plperl/GNUmakefile b/src/pl/plperl/GNUmakefile
index d7c8917f822..341c180c730 100644
--- a/src/pl/plperl/GNUmakefile
+++ b/src/pl/plperl/GNUmakefile
@@ -75,6 +75,8 @@ endif
 # where to find xsubpp for building XS.
 XSUBPPDIR = $(shell $(PERL) -e 'use List::Util qw(first); print first { -r "$$_/ExtUtils/xsubpp" } @INC')
 
+INSTALL_HDRS := $(shell grep -v '^\#' $(srcdir)/install_headers.list | grep -v '^$$')
+
 include $(top_srcdir)/src/Makefile.shlib
 
 plperl.o: perlchunks.h plperl_opmask.h
@@ -108,11 +110,11 @@ uninstall: uninstall-lib uninstall-data
 
 install-data: installdirs
 	$(INSTALL_DATA) $(addprefix $(srcdir)/, $(DATA)) '$(DESTDIR)$(datadir)/extension/'
-	$(INSTALL_DATA) $(srcdir)/plperl.h $(srcdir)/plperl_system.h $(srcdir)/ppport.h '$(DESTDIR)$(includedir_server)'
+	$(INSTALL_DATA) $(addprefix $(srcdir)/,$(INSTALL_HDRS)) '$(DESTDIR)$(includedir_server)'
 
 uninstall-data:
 	rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(DATA)))
-	rm -f $(addprefix '$(DESTDIR)$(includedir_server)'/, plperl.h plperl_system.h ppport.h)
+	rm -f $(addprefix '$(DESTDIR)$(includedir_server)'/, $(INSTALL_HDRS))
 
 .PHONY: install-data uninstall-data
 
diff --git a/src/pl/plperl/install_headers.list b/src/pl/plperl/install_headers.list
new file mode 100644
index 00000000000..f443f21887f
--- /dev/null
+++ b/src/pl/plperl/install_headers.list
@@ -0,0 +1,4 @@
+# PL/Perl headers installed to $(includedir_server)
+plperl.h
+plperl_system.h
+ppport.h
diff --git a/src/pl/plperl/meson.build b/src/pl/plperl/meson.build
index ff41812ca46..5aaa18aa93b 100644
--- a/src/pl/plperl/meson.build
+++ b/src/pl/plperl/meson.build
@@ -69,12 +69,14 @@ install_data(
   install_dir: dir_data_extension,
 )
 
-install_headers(
-  'plperl.h',
-  'plperl_system.h',
-  'ppport.h',
-  install_dir: dir_include_server,
-)
+_h = []
+foreach l : fs.read('install_headers.list').strip().split('\n')
+  l = l.strip()
+  if l != '' and not l.startswith('#')
+    _h += l
+  endif
+endforeach
+install_headers(_h, install_dir: dir_include_server)
 
 tests += {
   'name': 'plperl',
diff --git a/src/pl/plpgsql/src/Makefile b/src/pl/plpgsql/src/Makefile
index 63cb96fae3e..e9e91a99070 100644
--- a/src/pl/plpgsql/src/Makefile
+++ b/src/pl/plpgsql/src/Makefile
@@ -42,6 +42,8 @@ TOOLSDIR = $(top_srcdir)/src/tools
 GEN_KEYWORDLIST = $(PERL) -I $(TOOLSDIR) $(TOOLSDIR)/gen_keywordlist.pl
 GEN_KEYWORDLIST_DEPS = $(TOOLSDIR)/gen_keywordlist.pl $(TOOLSDIR)/PerfectHash.pm
 
+INSTALL_HDRS := $(shell grep -v '^\#' $(srcdir)/install_headers.list | grep -v '^$$')
+
 all: all-lib
 
 # Shared library stuff
@@ -59,15 +61,14 @@ uninstall: uninstall-lib uninstall-data uninstall-headers
 install-data: installdirs
 	$(INSTALL_DATA) $(addprefix $(srcdir)/, $(DATA)) '$(DESTDIR)$(datadir)/extension/'
 
-# The plpgsql.h header file is needed by instrumentation plugins
 install-headers: installdirs
-	$(INSTALL_DATA) '$(srcdir)/plpgsql.h' '$(DESTDIR)$(includedir_server)'
+	$(INSTALL_DATA) $(addprefix $(srcdir)/,$(INSTALL_HDRS)) '$(DESTDIR)$(includedir_server)'
 
 uninstall-data:
 	rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(DATA)))
 
 uninstall-headers:
-	rm -f '$(DESTDIR)$(includedir_server)/plpgsql.h'
+	rm -f $(addprefix '$(DESTDIR)$(includedir_server)'/, $(INSTALL_HDRS))
 
 .PHONY: install-data install-headers uninstall-data uninstall-headers
 
diff --git a/src/pl/plpgsql/src/install_headers.list b/src/pl/plpgsql/src/install_headers.list
new file mode 100644
index 00000000000..a39a9485d16
--- /dev/null
+++ b/src/pl/plpgsql/src/install_headers.list
@@ -0,0 +1,2 @@
+# PL/pgSQL headers installed to $(includedir_server)
+plpgsql.h
diff --git a/src/pl/plpgsql/src/meson.build b/src/pl/plpgsql/src/meson.build
index 6ff27006cfc..7f84b15b15f 100644
--- a/src/pl/plpgsql/src/meson.build
+++ b/src/pl/plpgsql/src/meson.build
@@ -63,10 +63,14 @@ install_data(
   install_dir: dir_data_extension,
 )
 
-install_headers(
-  'plpgsql.h',
-  install_dir: dir_include_server
-)
+_h = []
+foreach l : fs.read('install_headers.list').strip().split('\n')
+  l = l.strip()
+  if l != '' and not l.startswith('#')
+    _h += l
+  endif
+endforeach
+install_headers(_h, install_dir: dir_include_server)
 
 
 tests += {
diff --git a/src/pl/plpython/Makefile b/src/pl/plpython/Makefile
index 25f295c3709..2b82b6f89c6 100644
--- a/src/pl/plpython/Makefile
+++ b/src/pl/plpython/Makefile
@@ -37,21 +37,8 @@ OBJS = \
 DATA = $(NAME)u.control $(NAME)u--1.0.sql
 
 # header files to install - it's not clear which of these might be needed
-# so install them all.
-INCS = 	plpython.h \
-	plpython_system.h \
-	plpy_cursorobject.h \
-	plpy_elog.h \
-	plpy_exec.h \
-	plpy_main.h \
-	plpy_planobject.h \
-	plpy_plpymodule.h \
-	plpy_procedure.h \
-	plpy_resultobject.h \
-	plpy_spi.h \
-	plpy_subxactobject.h \
-	plpy_typeio.h \
-	plpy_util.h
+# so install them all.  See install_headers.list for the list.
+INCS := $(shell grep -v '^\#' $(srcdir)/install_headers.list | grep -v '^$$')
 
 # Python on win32 ships with import libraries only for Microsoft Visual C++,
 # which are not compatible with mingw gcc. Therefore we need to build a
diff --git a/src/pl/plpython/install_headers.list b/src/pl/plpython/install_headers.list
new file mode 100644
index 00000000000..e9a39405cb7
--- /dev/null
+++ b/src/pl/plpython/install_headers.list
@@ -0,0 +1,15 @@
+# PL/Python headers installed to $(includedir_server)
+plpy_cursorobject.h
+plpy_elog.h
+plpy_exec.h
+plpy_main.h
+plpy_planobject.h
+plpy_plpymodule.h
+plpy_procedure.h
+plpy_resultobject.h
+plpy_spi.h
+plpy_subxactobject.h
+plpy_typeio.h
+plpy_util.h
+plpython.h
+plpython_system.h
diff --git a/src/pl/plpython/meson.build b/src/pl/plpython/meson.build
index ef8aba56539..2a973e25d15 100644
--- a/src/pl/plpython/meson.build
+++ b/src/pl/plpython/meson.build
@@ -53,23 +53,14 @@ install_data(
   install_dir: dir_data_extension,
 )
 
-install_headers(
-  'plpy_cursorobject.h',
-  'plpy_elog.h',
-  'plpy_exec.h',
-  'plpy_main.h',
-  'plpy_planobject.h',
-  'plpy_plpymodule.h',
-  'plpy_procedure.h',
-  'plpy_resultobject.h',
-  'plpy_spi.h',
-  'plpy_subxactobject.h',
-  'plpy_typeio.h',
-  'plpy_util.h',
-  'plpython.h',
-  'plpython_system.h',
-  install_dir: dir_include_server,
-)
+_h = []
+foreach l : fs.read('install_headers.list').strip().split('\n')
+  l = l.strip()
+  if l != '' and not l.startswith('#')
+    _h += l
+  endif
+endforeach
+install_headers(_h, install_dir: dir_include_server)
 
 plpython_regress = [
   'plpython_schema',
-- 
2.43.0



  [application/octet-stream] 0003-Consolidate-libpq-headers-into-central-public-intern.patch (5.9K, 4-0003-Consolidate-libpq-headers-into-central-public-intern.patch)
  download | inline diff:
From eb9d3d64a8653dac3e4c85f7b38e03520b376fcb Mon Sep 17 00:00:00 2001
From: Zsolt Parragi <[email protected]>
Date: Sat, 14 Mar 2026 15:33:43 +0000
Subject: [PATCH 3/3] Consolidate libpq headers into central public/internal
 list files

Move the libpq public and internal header entries into the central
list files in src/include/. Both src/include/ and src/interfaces/libpq/
now read from the same lists and filter by local file existence:
$(wildcard) in make, fs.is_file() in meson.

This eliminates the separate per-directory list files for libpq,
giving a single view of all public and internal headers regardless
of which source directory they live in.
---
 src/include/Makefile                       | 6 ++++--
 src/include/internal_headers.list          | 9 ++++++++-
 src/include/meson.build                    | 2 +-
 src/include/public_headers.list            | 6 +++++-
 src/interfaces/libpq/Makefile              | 6 ++++--
 src/interfaces/libpq/internal_headers.list | 4 ----
 src/interfaces/libpq/meson.build           | 8 ++++----
 src/interfaces/libpq/public_headers.list   | 3 ---
 8 files changed, 26 insertions(+), 18 deletions(-)
 delete mode 100644 src/interfaces/libpq/internal_headers.list
 delete mode 100644 src/interfaces/libpq/public_headers.list

diff --git a/src/include/Makefile b/src/include/Makefile
index f2bed2578a5..c8881ad4d2c 100644
--- a/src/include/Makefile
+++ b/src/include/Makefile
@@ -12,8 +12,10 @@ subdir = src/include
 top_builddir = ../..
 include $(top_builddir)/src/Makefile.global
 
-PUBLIC_HEADERS := $(shell grep -v '^\#' $(srcdir)/public_headers.list | grep -v '^$$')
-INTERNAL_HEADERS := $(shell grep -v '^\#' $(srcdir)/internal_headers.list | grep -v '^$$')
+_ALL_PUBLIC := $(shell grep -v '^\#' $(srcdir)/public_headers.list | grep -v '^$$')
+PUBLIC_HEADERS := $(foreach h,$(_ALL_PUBLIC),$(if $(wildcard $(srcdir)/$(h)),$(h)))
+_ALL_INTERNAL := $(shell grep -v '^\#' $(srcdir)/internal_headers.list | grep -v '^$$')
+INTERNAL_HEADERS := $(foreach h,$(_ALL_INTERNAL),$(if $(wildcard $(srcdir)/$(h)),$(h)))
 SERVER_HEADERS := $(shell grep -v '^\#' $(srcdir)/server_headers.list | grep -v '^$$')
 
 all: pg_config.h pg_config_os.h
diff --git a/src/include/internal_headers.list b/src/include/internal_headers.list
index 8e12f4d7cd6..86b99b8a823 100644
--- a/src/include/internal_headers.list
+++ b/src/include/internal_headers.list
@@ -2,10 +2,17 @@
 #
 # These headers are needed by the not-so-public headers of the interfaces,
 # i.e. for client library development.
+#
+# Each source directory installs only the entries that exist locally.
 
+# src/include
 c.h
 port.h
 postgres_fe.h
-
 libpq/pqcomm.h
 libpq/protocol.h
+
+# src/interfaces/libpq
+fe-auth-sasl.h
+libpq-int.h
+pqexpbuffer.h
diff --git a/src/include/meson.build b/src/include/meson.build
index c03e508b961..9279083280c 100644
--- a/src/include/meson.build
+++ b/src/include/meson.build
@@ -83,7 +83,7 @@ foreach list_file, base_dir : _header_lists
   batch = []
   foreach line : fs.read(list_file).strip().split('\n')
     f = line.strip()
-    if f == '' or f.startswith('#')
+    if f == '' or f.startswith('#') or not fs.is_file(f)
       continue
     endif
     d = fs.parent(f)
diff --git a/src/include/public_headers.list b/src/include/public_headers.list
index 2cd1df6f8ab..bacd3854341 100644
--- a/src/include/public_headers.list
+++ b/src/include/public_headers.list
@@ -6,7 +6,11 @@
 #
 # Each source directory installs only the entries that exist locally.
 
+# src/include
 pg_config_manual.h
 postgres_ext.h
-
 libpq/libpq-fs.h
+
+# src/interfaces/libpq
+libpq-events.h
+libpq-fe.h
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index b9319fab869..9d599f20e05 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -15,8 +15,10 @@ subdir = src/interfaces/libpq
 top_builddir = ../../..
 include $(top_builddir)/src/Makefile.global
 
-PUBLIC_HEADERS := $(shell grep -v '^\#' $(srcdir)/public_headers.list | grep -v '^$$')
-INTERNAL_HEADERS := $(shell grep -v '^\#' $(srcdir)/internal_headers.list | grep -v '^$$')
+_ALL_PUBLIC := $(shell grep -v '^\#' $(top_srcdir)/src/include/public_headers.list | grep -v '^$$')
+PUBLIC_HEADERS := $(foreach h,$(_ALL_PUBLIC),$(if $(wildcard $(srcdir)/$(h)),$(h)))
+_ALL_INTERNAL := $(shell grep -v '^\#' $(top_srcdir)/src/include/internal_headers.list | grep -v '^$$')
+INTERNAL_HEADERS := $(foreach h,$(_ALL_INTERNAL),$(if $(wildcard $(srcdir)/$(h)),$(h)))
 
 export with_ssl with_gssapi with_krb_srvnam
 
diff --git a/src/interfaces/libpq/internal_headers.list b/src/interfaces/libpq/internal_headers.list
deleted file mode 100644
index 635f735b0ad..00000000000
--- a/src/interfaces/libpq/internal_headers.list
+++ /dev/null
@@ -1,4 +0,0 @@
-# Internal libpq headers installed to $(includedir_internal)
-fe-auth-sasl.h
-libpq-int.h
-pqexpbuffer.h
diff --git a/src/interfaces/libpq/meson.build b/src/interfaces/libpq/meson.build
index 09f7f8c85c0..3776fe57e84 100644
--- a/src/interfaces/libpq/meson.build
+++ b/src/interfaces/libpq/meson.build
@@ -133,18 +133,18 @@ pkgconfig.generate(
 )
 
 _h = []
-foreach l : fs.read('public_headers.list').strip().split('\n')
+foreach l : fs.read('../../include/public_headers.list').strip().split('\n')
   l = l.strip()
-  if l != '' and not l.startswith('#')
+  if l != '' and not l.startswith('#') and fs.is_file(l)
     _h += l
   endif
 endforeach
 install_headers(_h)
 
 _h = []
-foreach l : fs.read('internal_headers.list').strip().split('\n')
+foreach l : fs.read('../../include/internal_headers.list').strip().split('\n')
   l = l.strip()
-  if l != '' and not l.startswith('#')
+  if l != '' and not l.startswith('#') and fs.is_file(l)
     _h += l
   endif
 endforeach
diff --git a/src/interfaces/libpq/public_headers.list b/src/interfaces/libpq/public_headers.list
deleted file mode 100644
index 26dbe72b8ea..00000000000
--- a/src/interfaces/libpq/public_headers.list
+++ /dev/null
@@ -1,3 +0,0 @@
-# Public libpq headers installed to $(includedir)
-libpq-events.h
-libpq-fe.h
-- 
2.43.0



view thread (2+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected]
  Subject: Re: Proposal: common explicit lists for installed headers
  In-Reply-To: <CAN4CZFN=NaOVXmoPXpW11K93ZgZFUp_20BOU7Jj3vWJJepdfdQ@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox