Both follow-up patches are attached in order on top of your public v4. Patch 1 handles CMake include directories returned as strings or lists and escapes spaces in exported flags. Patch 2 keeps PostgreSQL headers ahead of extra include paths, passes those paths to all six fallback header checks, and exports them through PGXS and pg_config.
I applied v4 and these exact patches to PostgreSQL master 6b9f40d49ae33eb0b4a7c77666fe4971ef7ba087. On hosted Windows x64 and ARM64, the include-export cases passed with Meson 0.57.2 and 1.11.2. All six fallback header probes and the psql header-order check passed on both architectures. The v4 control reproduced the wrong-header failure. Hosted run: https://github.com/Harrison-Booth/postgresql-windows-ci/actions/runs/39595041637 Patch 2 addresses the same header-order concern as CF6056, but also covers fallback probes and exported flags. I haven't combined or tested both implementations together. These focused checks don't cover a full server, installed extension, or PGXS runtime. Could you review the attached follow-up patches, especially patch 2's header-order approach? Best, Harrison
From 428e3c5e62505566ada32ac85b218b55f993947f Mon Sep 17 00:00:00 2001 From: Harrison Booth <[email protected]> Date: Tue, 20 Oct 2026 10:00:58 -0500 Subject: [PATCH 1/2] Meson: handle CMake include directory lists and spaces Normalize CMake include directory results before splitting them, so both string and array values are accepted. Escape spaces in the compiler flags exported for PGXS. --- meson.build | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/meson.build b/meson.build index be77959..6bf91cc 100644 --- a/meson.build +++ b/meson.build @@ -3417,10 +3417,13 @@ foreach dep_name, dep_info : pgxs_flag_deps foreach dep : dep_objs incdirs = dep.get_variable(cmake: 'PACKAGE_INCLUDE_DIRS', default_value: '') - foreach incdir_raw : incdirs.split(';') + incdirs_list = [] + incdirs_list += incdirs + foreach incdir_raw : ';'.join(incdirs_list).split(';') incdir = incdir_raw.strip() - if incdir != '' and '-I' + incdir not in dep_flags - dep_flags += '-I' + incdir + incflag = '-I' + '\\ '.join(incdir.split(' ')) + if incdir != '' and incflag not in dep_flags + dep_flags += incflag endif endforeach endforeach -- 2.53.0.windows.2
From 5199e6430fb57381de3f203b9e5b6c30f05f3a73 Mon Sep 17 00:00:00 2001 From: Harrison Booth <[email protected]> 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
