Subject: [PATCH] Add `headerscheck` run_target to meson

From: Miłosz Bieniek <[email-masked]>
Date: Thu, 27 Nov 2025 10:28:17 +0100

Hi,
While reviewing a patch I noticed that we have a `make -s headerscheck` but
there is no equivalent in meson.
I prepared a small patch that adds `headerscheck` and `cpluspluscheck`
targets.

Best Regards,
Miłosz Bieniek

---

From: Peter Eisentraut <[email-masked]>
Date: Fri, 28 Nov 2025 12:53:25 +0100

On 27.11.25 10:28, Miłosz Bieniek wrote:
> While reviewing a patch I noticed that we have a `make -s headerscheck` 
> but there is no equivalent in meson.

This would be good to have, but I don't think your patch works.  It 
seems you need to add the srcdir and builddir command-line arguments to 
the invocations.

---

From: Miłosz Bieniek <[email-masked]>
Date: Fri, 28 Nov 2025 13:58:01 +0100

> seems you need to add the srcdir and builddir command-line arguments to

I think you are right. I added srcdir and builddir arguments.

---

From: Nazir Bilal Yavuz <[email-masked]>
Date: Fri, 28 Nov 2025 18:05:12 +0300

Hi,

Thank you for working on this!

> I think you are right. I added srcdir and builddir arguments.

The headerscheck script pulls some information from Makefile.global
after the configure [1] but meson does not generate a full version of
Makefile.global [2], so it does not have the required information to
check perl and python headers. If you run 'meson compile
headerscheck', you get errors like:

In file included from
/home/nbyavuz/Desktop/projects/postgres/src/pl/plperl/plperl.h:25,
                 from /tmp/headerscheck.YxsZhn/test.c:2:
/home/nbyavuz/Desktop/projects/postgres/src/pl/plperl/plperl_system.h:85:10:
fatal error: EXTERN.h: No such file or directory
   85 | #include <EXTERN.h>
      |          ^~~~~~~~~~
compilation terminated.

In file included from
/home/nbyavuz/Desktop/projects/postgres/src/pl/plpython/plpython.h:39,
                 from
/home/nbyavuz/Desktop/projects/postgres/src/pl/plpython/plpy_plpymodule.h:8,
                 from /tmp/headerscheck.YxsZhn/test.c:2:
/home/nbyavuz/Desktop/projects/postgres/src/pl/plpython/plpython_system.h:50:10:
fatal error: Python.h: No such file or directory
   50 | #include <Python.h>
      |          ^~~~~~~~~~
compilation terminated.

-----

[1.1] src/tools/pginclude/headerscheck
# Needs to be run after configuring and creating all generated headers.
# It's advisable to configure --with-perl --with-python, else you're
# likely to get errors from associated headers.

[1.2] src/tools/pginclude/headerscheck
# Pull some info from configure's results.
MGLOB="$builddir/src/Makefile.global"
CPPFLAGS=`sed -n 's/^CPPFLAGS[     ]*=[     ]*//p' "$MGLOB"`
CFLAGS=`sed -n 's/^CFLAGS[     ]*=[     ]*//p' "$MGLOB"`
ICU_CFLAGS=`sed -n 's/^ICU_CFLAGS[     ]*=[     ]*//p' "$MGLOB"`
CC=`sed -n 's/^CC[     ]*=[     ]*//p' "$MGLOB"`
CXX=`sed -n 's/^CXX[     ]*=[     ]*//p' "$MGLOB"`
PG_SYSROOT=`sed -n 's/^PG_SYSROOT[     ]*=[     ]*//p' "$MGLOB"`
perl_includespec=`sed -n 's/^perl_includespec[     ]*=[     ]*//p' "$MGLOB"`
python_includespec=`sed -n 's/^python_includespec[     ]*=[     ]*//p' "$MGLOB"`

[2] src/meson.build
makefile_global = configure_file(
  input: 'Makefile.global.in',
  output: 'Makefile.global',
  configuration: pgxs_cdata,
  install: true,
  install_dir: dir_pgxs / 'src',
)
configure_files += makefile_global

-- 
Regards,
Nazir Bilal Yavuz
Microsoft

---

From: Nazir Bilal Yavuz <[email-masked]>
Date: Fri, 28 Nov 2025 18:17:19 +0300

Hi,

> headerscheck', you get errors like:

Sorry, I clicked send early.

Two solutions came to my mind but I am not sure which one is better:

1) We can add missing information to the generated Makefile.global in
the meson.build.

2) We can send required information as arguments to the headerscheck script.

Any thoughts or suggestions?

-- 
Regards,
Nazir Bilal Yavuz
Microsoft

---

From: Miłosz Bieniek <[email-masked]>
Date: Sat, 29 Nov 2025 12:07:05 +0100

> Any thoughts or suggestions?

Thank you for the detailed response.
I initially thought the errors with `#include <Python.h>` and
`#include <EXTREN.h>` were only an issue with my local setup.
If I understand correctly, your first proposal would address this
problem without requiring integration with the headerscheck script,
which in my opinion would be a cleaner solution.
However, I would definitely like to hear what others think as well.

---

From: Bilal Yavuz <[email-masked]>
Date: Thu, 4 Dec 2025 10:09:33 +0300

Hi,

> However, I would definitely like to hear what others think as well.

I wanted to experiment with the first proposal and it turns out I need
to edit the headerscheck script.

There are 3 patches attached:

0001 adds python_includespec and perl_includespec variables to the
Makefile.global of the meson build.

0002 adds headerscheck target to meson build like you do but with 2
extra changes. First one is that, I moved the headerscheck script to a
variable and used it in the target commands. Second one is that,
headerscheck script could not find the perl_includespec and
python_includespec variables because of the tabs in the sed command, I
changed them with '[:space:]' and it worked. I am not sure if that is
the correct fix but I just wanted to see if the script will work.

0003 adds icu_flags option to the meson build and sets 'ICU_CFLAGS'
Makefile.global variable to that option. This change is not needed for
the headerscheck script to work but I saw that was missing and just
wanted to show it. If we want to add that, this probably needs its own
thread.

--
Regards,
Nazir Bilal Yavuz
Microsoft
From 44a7e1227fd4a57472b9dffe69f15813e0b2734c Mon Sep 17 00:00:00 2001
From: Nazir Bilal Yavuz <[email-masked]>
Date: Sat, 29 Nov 2025 19:25:20 +0300
Subject: [PATCH v3 1/3] meson: Add {python|perl}_includespec to the
 Makefile.global

---
 src/makefiles/meson.build | 7 +++++--
 meson.build               | 9 +++++++++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/makefiles/meson.build b/src/makefiles/meson.build
index 0def244c901..3c732a94653 100644
--- a/src/makefiles/meson.build
+++ b/src/makefiles/meson.build
@@ -77,6 +77,9 @@ pgxs_kv = {
   'STRIP_STATIC_LIB': ' '.join(strip_static_cmd),
   'STRIP_SHARED_LIB': ' '.join(strip_shared_cmd),
 
+  'python_includespec': python_includespec,
+  'perl_includespec': perl_includespec,
+
   # these seem to be standard these days
   'MKDIR_P': 'mkdir -p',
   'LN_S': 'ln -s',
@@ -181,8 +184,8 @@ pgxs_empty = [
   'PG_TEST_EXTRA',
   'DTRACEFLAGS', # only server has dtrace probes
 
-  'perl_archlibexp', 'perl_embed_ccflags', 'perl_embed_ldflags', 'perl_includespec', 'perl_privlibexp',
-  'python_additional_libs', 'python_includespec', 'python_libdir', 'python_libspec', 'python_majorversion', 'python_version',
+  'perl_archlibexp', 'perl_embed_ccflags', 'perl_embed_ldflags', 'perl_privlibexp',
+  'python_additional_libs', 'python_libdir', 'python_libspec', 'python_majorversion', 'python_version',
 
   # possible that some of these are referenced explicitly in pgxs makefiles?
   # For now not worth it.
diff --git a/meson.build b/meson.build
index 6e7ddd74683..0a68ebf1598 100644
--- a/meson.build
+++ b/meson.build
@@ -1176,6 +1176,7 @@ endif
 # Library: Perl (for plperl)
 ###############################################################
 
+perl_includespec = ''
 perlopt = get_option('plperl')
 perl_dep = not_found_dep
 perlversion = ''
@@ -1202,6 +1203,7 @@ if not perlopt.disabled()
     useshrplib = run_command(perl_conf_cmd, 'useshrplib', check: true).stdout()
 
     perl_inc_dir = '@0@/CORE'.format(archlibexp)
+    perl_includespec = '-I@0@'.format(perl_inc_dir)
 
     if perlversion.version_compare('< 5.14')
       perl_may_work = false
@@ -1220,6 +1222,7 @@ if not perlopt.disabled()
     if not fs.is_file('@0@/perl.h'.format(perl_inc_dir)) and \
        fs.is_file('@0@@1@/perl.h'.format(pg_sysroot, perl_inc_dir))
       perl_ccflags = ['-iwithsysroot', perl_inc_dir]
+      perl_includespec = '-iwithsysroot @0@/CORE'.format(archlibexp)
     endif
 
     # check compiler finds header
@@ -1322,6 +1325,7 @@ endif
 # Library: Python (for plpython)
 ###############################################################
 
+python_includespec = ''
 pyopt = get_option('plpython')
 python3_dep = not_found_dep
 if not pyopt.disabled()
@@ -1334,6 +1338,11 @@ if not pyopt.disabled()
       python3_dep = not_found_dep
     endif
   endif
+
+  if python3_dep.found()
+    command = [python, '-c', 'import sysconfig; print("-I" + sysconfig.get_config_var("INCLUDEPY"))']
+    python_includespec = run_command(command, check: true).stdout().strip()
+  endif
 endif

-- 
2.51.0

From e20ac980fd75125b136cb808ca90717e0565125f Mon Sep 17 00:00:00 2001
From: moozzi <[email-masked]>
Date: Fri, 28 Nov 2025 13:54:13 +0100
Subject: [PATCH v3 2/3] Add `headerscheck` run_target to meson

---
 meson.build                      | 15 +++++++++++++++
 src/tools/pginclude/headerscheck |  4 ++--
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/meson.build b/meson.build
index 0a68ebf1598..2ca8d750a3f 100644
--- a/meson.build
+++ b/meson.build
@@ -3909,6 +3909,21 @@ endif

+###############################################################
+# headerscheck
+###############################################################
+
+headerscheck = files('src/tools/pginclude/headerscheck')
+run_target('headerscheck',
+  command: [headerscheck, meson.project_source_root(), meson.project_build_root()]
+)
+
+run_target('cpluspluscheck',
+  command: [headerscheck, '--cplusplus', meson.project_source_root(), meson.project_build_root()]
+)
+
+
+
 ###############################################################
 # The End, The End, My Friend
 ###############################################################
diff --git a/src/tools/pginclude/headerscheck b/src/tools/pginclude/headerscheck
index a52a5580bdc..a96a462a5ef 100755
--- a/src/tools/pginclude/headerscheck
+++ b/src/tools/pginclude/headerscheck
@@ -48,8 +48,8 @@ ICU_CFLAGS=`sed -n 's/^ICU_CFLAGS[ 	]*=[ 	]*//p' "$MGLOB"`
 CC=`sed -n 's/^CC[ 	]*=[ 	]*//p' "$MGLOB"`
 CXX=`sed -n 's/^CXX[ 	]*=[ 	]*//p' "$MGLOB"`
 PG_SYSROOT=`sed -n 's/^PG_SYSROOT[ 	]*=[ 	]*//p' "$MGLOB"`
-perl_includespec=`sed -n 's/^perl_includespec[ 	]*=[ 	]*//p' "$MGLOB"`
-python_includespec=`sed -n 's/^python_includespec[ 	]*=[ 	]*//p' "$MGLOB"`
+perl_includespec=`sed -n 's/^perl_includespec[[:space:]]*=[[:space:]]*//p' "$MGLOB"`
+python_includespec=`sed -n 's/^python_includespec[[:space:]]*=[[:space:]]*//p' "$MGLOB"`
 
 # needed on Darwin
 CPPFLAGS=`echo "$CPPFLAGS" | sed "s|\\\$(PG_SYSROOT)|$PG_SYSROOT|g"`
-- 
2.51.0

From b9001a654dd97ea63572ff52ab43caa60be4fc19 Mon Sep 17 00:00:00 2001
From: Nazir Bilal Yavuz <[email-masked]>
Date: Sat, 29 Nov 2025 19:06:28 +0300
Subject: [PATCH v3 3/3] meson: Add icu_flags option

---
 src/makefiles/meson.build        | 4 ++--
 meson_options.txt                | 3 +++
 src/tools/pginclude/headerscheck | 2 +-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/makefiles/meson.build b/src/makefiles/meson.build
index 3c732a94653..5046e9cb496 100644
--- a/src/makefiles/meson.build
+++ b/src/makefiles/meson.build
@@ -116,6 +116,8 @@ pgxs_kv = {
   'BITCODE_CFLAGS': '',
   'BITCODE_CXXFLAGS': '',
 
+  'ICU_CFLAGS': get_option('icu_cflags'),
+
   'BISONFLAGS': ' '.join(bison_flags),
   'FLEXFLAGS': ' '.join(flex_flags),
 
@@ -155,8 +157,6 @@ pgxs_bins = {
 }
 
 pgxs_empty = [
-  'ICU_CFLAGS', # needs to be added, included by public server headers
-
   # hard to see why we'd need either?
   'ZIC',
   'TCLSH',
diff --git a/meson_options.txt b/meson_options.txt
index 06bf5627d3c..ca79e117d09 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -70,6 +70,9 @@ option('darwin_sysroot', type: 'string', value: '',
 option('rpath', type: 'boolean', value: true,
   description: 'Embed shared library search path in executables')
 
+option('icu_cflags', type: 'string', value: '',
+  description: 'C compiler flags for ICU, overriding pkg-config')
+
 
 # External dependencies
 
diff --git a/src/tools/pginclude/headerscheck b/src/tools/pginclude/headerscheck
index a96a462a5ef..1a589e4b13c 100755
--- a/src/tools/pginclude/headerscheck
+++ b/src/tools/pginclude/headerscheck
@@ -44,7 +44,7 @@ CXXFLAGS=${CXXFLAGS:- -fsyntax-only -Wall}
 MGLOB="$builddir/src/Makefile.global"
 CPPFLAGS=`sed -n 's/^CPPFLAGS[ 	]*=[ 	]*//p' "$MGLOB"`
 CFLAGS=`sed -n 's/^CFLAGS[ 	]*=[ 	]*//p' "$MGLOB"`
-ICU_CFLAGS=`sed -n 's/^ICU_CFLAGS[ 	]*=[ 	]*//p' "$MGLOB"`
+ICU_CFLAGS=`sed -n 's/^ICU_CFLAGS[[:space:]]*=[[:space:]]*//p' "$MGLOB"`
 CC=`sed -n 's/^CC[ 	]*=[ 	]*//p' "$MGLOB"`
 CXX=`sed -n 's/^CXX[ 	]*=[ 	]*//p' "$MGLOB"`
 PG_SYSROOT=`sed -n 's/^PG_SYSROOT[ 	]*=[ 	]*//p' "$MGLOB"`
-- 
2.51.0

---

From: Peter Eisentraut <[email-masked]>
Date: Wed, 18 Mar 2026 12:59:51 +0100

On 18.03.26 11:56, Peter Eisentraut wrote:
> On 04.12.25 08:09, Bilal Yavuz wrote:
> Committed that, with some light cosmetic ordering changes.
> 
> Committed that, but without the regular expression changes.  I don't 
> understand why those would be needed.  Please provide more information 
> if necessary.  It worked for me without it.

I need another tweak for the cpluspluscheck.

In meson, the distribution of the include flags between CPPFLAGS, 
CFLAGS, and CXXFLAGS ends up being a bit different, and we need to get a 
few -I options from CXXFLAGS in my case.

I have attached two different variants for how to do this.  The first 
one just gets the -D and -I flags from CXXFLAGS.  This preserves most of 
the existing behavior.  The second aligns more with how CFLAGS works and 
removes the ability to override CXXFLAGS from the command line.  This is 
probably now better since we have more support for getting correct CXX 
and CXXFLAGS in the build system.  But it might be a change for some users.

Thoughts?
From ec1da8265908b6d6761973fda54aa0008dd033c5 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Wed, 18 Mar 2026 12:58:47 +0100
Subject: [PATCH] headerscheck: Get CXXFLAGS (variant 1)

---
 src/tools/pginclude/headerscheck | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/tools/pginclude/headerscheck b/src/tools/pginclude/headerscheck
index 3d3e371a8e1..4a66a194b46 100755
--- a/src/tools/pginclude/headerscheck
+++ b/src/tools/pginclude/headerscheck
@@ -44,6 +44,7 @@ CXXFLAGS=${CXXFLAGS:- -fsyntax-only -Wall}
 MGLOB="$builddir/src/Makefile.global"
 CPPFLAGS=`sed -n 's/^CPPFLAGS[ 	]*=[ 	]*//p' "$MGLOB"`
 CFLAGS=`sed -n 's/^CFLAGS[ 	]*=[ 	]*//p' "$MGLOB"`
+_CXXFLAGS=`sed -n 's/^CXXFLAGS[ 	]*=[ 	]*//p' "$MGLOB"`
 ICU_CFLAGS=`sed -n 's/^ICU_CFLAGS[ 	]*=[ 	]*//p' "$MGLOB"`
 LLVM_CPPFLAGS=`sed -n 's/^LLVM_CPPFLAGS[ 	]*=[ 	]*//p' "$MGLOB"`
 CC=`sed -n 's/^CC[ 	]*=[ 	]*//p' "$MGLOB"`
@@ -60,8 +61,8 @@ CPPFLAGS=`echo "$CPPFLAGS" | sed "s|\\\$(PG_SYSROOT)|$PG_SYSROOT|g"`
 if $cplusplus; then
 	ext=cpp
 	COMPILER=${CXX:-g++}
-	# Extract any -I and -D switches from CPPFLAGS.
-	for flag in $CPPFLAGS; do
+	# Extract any -I and -D switches from CPPFLAGS and CXXFLAGS from Makefile.global.
+	for flag in $CPPFLAGS $_CXXFLAGS; do
 	  case $flag in
 	    -I*|-D*) CXXPPFLAGS="$CXXPPFLAGS $flag";;
 	  esac
-- 
2.53.0

From 64a4d26eaaff6509fbb3fea0fb7e0997741acec1 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Wed, 18 Mar 2026 12:58:59 +0100
Subject: [PATCH] headerscheck: Get CXXFLAGS (variant 2)

---
 src/tools/pginclude/headerscheck | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/tools/pginclude/headerscheck b/src/tools/pginclude/headerscheck
index 3d3e371a8e1..72503c0cd89 100755
--- a/src/tools/pginclude/headerscheck
+++ b/src/tools/pginclude/headerscheck
@@ -37,13 +37,11 @@ fi
 
 me=`basename $0`
 
-# These switches are g++ specific, you may override if necessary.
-CXXFLAGS=${CXXFLAGS:- -fsyntax-only -Wall}
-
 # Pull some info from configure's results.
 MGLOB="$builddir/src/Makefile.global"
 CPPFLAGS=`sed -n 's/^CPPFLAGS[ 	]*=[ 	]*//p' "$MGLOB"`
 CFLAGS=`sed -n 's/^CFLAGS[ 	]*=[ 	]*//p' "$MGLOB"`
+CXXFLAGS=`sed -n 's/^CXXFLAGS[ 	]*=[ 	]*//p' "$MGLOB"`
 ICU_CFLAGS=`sed -n 's/^ICU_CFLAGS[ 	]*=[ 	]*//p' "$MGLOB"`
 LLVM_CPPFLAGS=`sed -n 's/^LLVM_CPPFLAGS[ 	]*=[ 	]*//p' "$MGLOB"`
 CC=`sed -n 's/^CC[ 	]*=[ 	]*//p' "$MGLOB"`
-- 
2.53.0

---

From: Nazir Bilal Yavuz <[email-masked]>
Date: Wed, 18 Mar 2026 18:36:56 +0300

Hi,

> > if necessary.  It worked for me without it.

It is working now. I can't reproduce the problem, it looks like it is
already fixed.

> and CXXFLAGS in the build system.  But it might be a change for some users.

I think we can go with the second variant first. If there is a
complaint, we can then consider switching to the first one. Does that
sound good? Also, second patch probably needs to remove lines below
from the src/tools/pginclude/README:

```
If you are using a non-g++-compatible C++ compiler, you may need to
override the script's CXXFLAGS setting by setting a suitable environment
value.
```

--
Regards,
Nazir Bilal Yavuz
Microsoft

---

From: Peter Eisentraut <[email-masked]>
Date: Mon, 23 Mar 2026 08:00:55 +0100

> override the script's CXXFLAGS setting by setting a suitable environment

Ok, done that way.