From 5199e6430fb57381de3f203b9e5b6c30f05f3a73 Mon Sep 17 00:00:00 2001
From: Harrison Booth <harrisontbooth@gmail.com>
Date: Tue, 20 Oct 2026 10:49:35 -0500
Subject: [PATCH 2/2] Keep external include flags after PostgreSQL headers

Pass extra_include_dirs as project arguments so explicit PostgreSQL source headers remain ahead of external include paths. Include those arguments in the six find_library() header probes, which otherwise would not see project arguments.

Export extra_include_dirs to PGXS and pg_config flags, normalizing Windows separators and escaping spaces. The focused export coverage is for paths containing spaces; this patch does not claim general Make or shell metacharacter serialization.

Based on the include-ordering approach in Andres Freund's CF6056 prototype and Thomas Munro's comments in that discussion. This follow-up also passes extra_include_dirs to the six fallback header probes and exports paths containing spaces for PGXS and pg_config.
---
 meson.build             | 47 +++++++++++++++++++++++++++++++++--------
 src/include/meson.build |  6 ++++--
 2 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/meson.build b/meson.build
index 6bf91cc..7f11401 100644
--- a/meson.build
+++ b/meson.build
@@ -115,7 +115,6 @@ endif
 ###############################################################
 
 postgres_inc_d = ['src/include']
-postgres_inc_d += get_option('extra_include_dirs')
 
 postgres_lib_d = get_option('extra_lib_dirs')
 
@@ -390,6 +389,26 @@ else
   error('unknown host system: @0@'.format(host_system))
 endif
 
+# While the most obvious way to implement extra_include_dirs would be to add
+# extra_include_dirs to postgres_inc_d, that turns out to not work well: For
+# some parts of the buildtree (e.g. src/interfaces/libpq or tools linking
+# against libpq) we need to add additional directories to be included, and
+# those directories need to take precedence over extra_include_dirs.
+# Pass extra include directories as project arguments. Meson adds project
+# arguments after explicit include_directories.
+#
+# An additional advantage is that this way the extra include directories are
+# included in pg_config --cppflags output, keeping the behavior consistent
+# with autoconf builds.
+extra_include_args = []
+pgxs_extra_include_args = []
+foreach extra_dir : get_option('extra_include_dirs')
+  extra_include_args += '-I@0@'.format(extra_dir)
+  normalized_extra_dir = '/'.join(extra_dir.split('\\'))
+  pgxs_extra_include_args += '-I' + '\\ '.join(
+    normalized_extra_dir.split(' '))
+endforeach
+
 
 
 ###############################################################
@@ -676,7 +695,7 @@ endif
 
 postgres_inc = [include_directories(postgres_inc_d)]
 test_lib_d = postgres_lib_d
-test_c_args = cppflags + cflags
+test_c_args = cppflags + extra_include_args + cflags
 
 
 
@@ -855,8 +874,10 @@ else
   # Before 2.5 openldap didn't have a pkg-config file, and it might not be
   # installed
   if not ldap.found()
-    ldap = cc.find_library('ldap', required: ldapopt, dirs: test_lib_d,
-      has_headers: 'ldap.h', header_include_directories: postgres_inc)
+    ldap = cc.find_library('ldap',
+      required: ldapopt, dirs: test_lib_d,
+      has_headers: 'ldap.h', header_args: test_c_args,
+      header_include_directories: postgres_inc)
 
     # The separate ldap_r library only exists in OpenLDAP < 2.5, and if we
     # have 2.5 or later, we shouldn't even probe for ldap_r (we might find a
@@ -870,8 +891,10 @@ else
     else
 
       # Use ldap_r for FE if available, else assume ldap is thread-safe.
-      ldap_r = cc.find_library('ldap_r', required: false, dirs: test_lib_d,
-        has_headers: 'ldap.h', header_include_directories: postgres_inc)
+      ldap_r = cc.find_library('ldap_r',
+        required: false, dirs: test_lib_d,
+        has_headers: 'ldap.h', header_args: test_c_args,
+        header_include_directories: postgres_inc)
       if not ldap_r.found()
         ldap_r = ldap
       else
@@ -1644,6 +1667,7 @@ if sslopt in ['auto', 'openssl']
   if not ssl.found()
     ssl_lib = cc.find_library('ssl',
       dirs: test_lib_d,
+      header_args: test_c_args,
       header_include_directories: postgres_inc,
       has_headers: ['openssl/ssl.h', 'openssl/err.h'],
       required: openssl_required)
@@ -1746,12 +1770,14 @@ if uuidopt != 'none'
     if not uuid.found()
       uuid = cc.find_library('ossp-uuid',
         required: false, dirs: test_lib_d,
-        has_headers: uuidheader, header_include_directories: postgres_inc)
+        has_headers: uuidheader, header_args: test_c_args,
+        header_include_directories: postgres_inc)
     endif
     if not uuid.found()
       uuid = cc.find_library('uuid',
         required: true, dirs: test_lib_d,
-        has_headers: uuidheader, header_include_directories: postgres_inc)
+        has_headers: uuidheader, header_args: test_c_args,
+        header_include_directories: postgres_inc)
     endif
   else
     error('unknown uuid build option value: @0@'.format(uuidopt))
@@ -3333,6 +3359,7 @@ if not nlsopt.disabled()
     else
       libintl = cc.find_library('intl',
         has_headers: ['libintl.h'], required: nlsopt,
+        header_args: test_c_args,
         header_include_directories: postgres_inc,
         dirs: test_lib_d)
     endif
@@ -3445,9 +3472,11 @@ endforeach
 # can add further args directly, or indirectly via dependencies
 add_project_arguments(cflags, language: ['c'])
 add_project_arguments(cppflags, language: ['c'])
+add_project_arguments(extra_include_args, language: ['c'])
 add_project_arguments(cflags_warn, language: ['c'])
 add_project_arguments(cxxflags, language: ['cpp'])
 add_project_arguments(cppflags, language: ['cpp'])
+add_project_arguments(extra_include_args, language: ['cpp'])
 add_project_arguments(cxxflags_warn, language: ['cpp'])
 add_project_link_arguments(ldflags, language: ['c', 'cpp'])
 
@@ -4378,7 +4407,7 @@ summary(
 
 summary(
   {
-    'CPP FLAGS': ' '.join(cppflags),
+    'CPP FLAGS': ' '.join(cppflags + extra_include_args),
     'C FLAGS, functional': ' '.join(cflags),
     'C FLAGS, warnings': ' '.join(cflags_warn),
     'C FLAGS, modules': ' '.join(cflags_mod),
diff --git a/src/include/meson.build b/src/include/meson.build
index 3791539..df3c09e 100644
--- a/src/include/meson.build
+++ b/src/include/meson.build
@@ -47,11 +47,13 @@ else
   var_cxx = 'g++'
   var_cxxflags = ''
 endif
-var_cppflags = ' '.join(cppflags + pgxs_dep_cflags['openssl'])
+var_cppflags = ' '.join(
+  cppflags + pgxs_extra_include_args + pgxs_dep_cflags['openssl'])
 # pg_config --cppflags also includes ICU_CFLAGS, as with autoconf, where
 # Makefile.global adds $(ICU_CFLAGS) to CPPFLAGS
 var_cppflags_pg_config = ' '.join(
-  cppflags + pgxs_dep_cflags['openssl'] + pgxs_dep_cflags['icu'])
+  cppflags + pgxs_extra_include_args + pgxs_dep_cflags['openssl'] +
+  pgxs_dep_cflags['icu'])
 var_cflags_sl = ' '.join(cc.get_supported_arguments('-fPIC'))
 # explicitly add -Wl,--as-needed, normally added by meson, but we want it for
 # PGXS compatibility
-- 
2.53.0.windows.2

