On Sat, Nov 1, 2025 at 7:14 AM Heikki Linnakangas <[email protected]> wrote: > The patch seems harmless enough to me, no objections to committing it. > However, I'm worried that we'll soon break it again. The new rule is > apparently "include libpq first", but we have no way of enforcing it.
Here's a new version of the original approach with fixes for some copy-and-pastes I'd missed, and a new patch to check the search order in CI. It adds a "poisoned" libpq-fe.h header into the search path to break the build step if you get it wrong in meson or configure (cf commit 4300d8b6 which fixed a case of this there). It fails like this: [01:45:21.825] In file included from ../src/include/fe_utils/connect_utils.h:15, [01:45:21.825] from ../src/bin/scripts/common.h:13, [01:45:21.825] from ../src/bin/scripts/vacuumdb.c:17: [01:45:21.825] /tmp/poisoned_headers/libpq-fe.h:1:2: error: #error "external header hides in-tree header" [01:45:21.825] 1 | #error "external header hides in-tree header" [01:45:21.825] | ^~~~~ There must surely be a more mesonic way to do this with declarations rather than the order in a flimsy list that is copied all over the place (I guess that is probably supposed to be thought of as an unordered set...?), but I'm not sure I was on the right path with my v2 as mentioned and it didn't survive this test. This approach is OK for now, I think... if someone ever shows up with a patch to tackle it more fundamentally, the order will presumably become more flexible, so the new order will still be valid but unimportant. Will wait another day for a better idea or objection to show up, and otherwise commit these to 16+.
From aa390e77bedf25c7bf53f8dc5c05b6e826ccbc88 Mon Sep 17 00:00:00 2001 From: Thomas Munro <[email protected]> Date: Mon, 14 Jul 2025 11:54:00 +1200 Subject: [PATCH v3 1/2] meson: Fix libpq header include order. On systems using -Dextra_include_dir that happen to have a copy of libpq installed there, it's important to put the libpq header search path ahead of -Dextra_include_dir. Reorder the dependencies to achieve that. This matches the order used by configure. There is probably a better way to do this using declarations rather than adjusting the order of many lists, but this works for now until someone shows up with a patch for that. Back-patch to 16, where meson arrived. Reviewed-by: Heikki Linnakangas <[email protected]> Discussion: https://postgr.es/m/CA+hUKGKispvxLyrBn3=3mp0bb1n+rbyr5ee2gucoksnweoo...@mail.gmail.com --- contrib/dblink/meson.build | 2 +- contrib/oid2name/meson.build | 2 +- contrib/postgres_fdw/meson.build | 2 +- contrib/vacuumlo/meson.build | 2 +- src/backend/replication/libpqwalreceiver/meson.build | 2 +- src/bin/initdb/meson.build | 2 +- src/bin/pg_amcheck/meson.build | 2 +- src/bin/pg_basebackup/meson.build | 4 ++-- src/bin/pg_combinebackup/meson.build | 2 +- src/bin/pg_ctl/meson.build | 2 +- src/bin/pg_dump/meson.build | 8 ++++---- src/bin/pg_rewind/meson.build | 2 +- src/bin/pg_upgrade/meson.build | 2 +- src/bin/pg_verifybackup/meson.build | 2 +- src/bin/pgbench/meson.build | 2 +- src/bin/psql/meson.build | 2 +- src/bin/scripts/meson.build | 8 ++++---- src/fe_utils/meson.build | 2 +- src/interfaces/ecpg/ecpglib/meson.build | 6 +++--- src/interfaces/ecpg/include/meson.build | 2 +- src/interfaces/ecpg/test/meson.build | 4 ++-- src/interfaces/ecpg/test/thread/meson.build | 2 +- src/interfaces/libpq/test/meson.build | 4 ++-- src/test/isolation/meson.build | 4 ++-- src/test/modules/libpq_pipeline/meson.build | 2 +- src/test/modules/oauth_validator/meson.build | 2 +- src/test/modules/test_escape/meson.build | 2 +- src/test/modules/test_int128/meson.build | 2 +- src/test/modules/test_json_parser/meson.build | 2 +- src/test/modules/test_oat_hooks/meson.build | 4 +++- src/test/regress/meson.build | 4 ++-- 31 files changed, 46 insertions(+), 44 deletions(-) diff --git a/contrib/dblink/meson.build b/contrib/dblink/meson.build index a19ce6cf4b9..28da26d3d45 100644 --- a/contrib/dblink/meson.build +++ b/contrib/dblink/meson.build @@ -13,7 +13,7 @@ endif dblink = shared_module('dblink', dblink_sources, kwargs: contrib_mod_args + { - 'dependencies': contrib_mod_args['dependencies'] + [libpq], + 'dependencies': [libpq] + contrib_mod_args['dependencies'], }, ) contrib_targets += dblink diff --git a/contrib/oid2name/meson.build b/contrib/oid2name/meson.build index 074f16acd72..dd958f00bdf 100644 --- a/contrib/oid2name/meson.build +++ b/contrib/oid2name/meson.build @@ -12,7 +12,7 @@ endif oid2name = executable('oid2name', oid2name_sources, - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args, ) contrib_targets += oid2name diff --git a/contrib/postgres_fdw/meson.build b/contrib/postgres_fdw/meson.build index aac89ffdde8..a2890251d69 100644 --- a/contrib/postgres_fdw/meson.build +++ b/contrib/postgres_fdw/meson.build @@ -17,7 +17,7 @@ endif postgres_fdw = shared_module('postgres_fdw', postgres_fdw_sources, kwargs: contrib_mod_args + { - 'dependencies': contrib_mod_args['dependencies'] + [libpq], + 'dependencies': [libpq] + contrib_mod_args['dependencies'], }, ) contrib_targets += postgres_fdw diff --git a/contrib/vacuumlo/meson.build b/contrib/vacuumlo/meson.build index deee1d2832d..51e8fe9a325 100644 --- a/contrib/vacuumlo/meson.build +++ b/contrib/vacuumlo/meson.build @@ -12,7 +12,7 @@ endif vacuumlo = executable('vacuumlo', vacuumlo_sources, - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args, ) contrib_targets += vacuumlo diff --git a/src/backend/replication/libpqwalreceiver/meson.build b/src/backend/replication/libpqwalreceiver/meson.build index 2150f31cfa3..5318a76e29d 100644 --- a/src/backend/replication/libpqwalreceiver/meson.build +++ b/src/backend/replication/libpqwalreceiver/meson.build @@ -14,7 +14,7 @@ libpqwalreceiver = shared_module('pqwalreceiver', libpqwalreceiver_sources, kwargs: pg_mod_args + { 'name_prefix': 'lib', - 'dependencies': pg_mod_args['dependencies'] + [libpq], + 'dependencies': [libpq] + pg_mod_args['dependencies'], } ) diff --git a/src/bin/initdb/meson.build b/src/bin/initdb/meson.build index 06958e370f3..b8584fe56de 100644 --- a/src/bin/initdb/meson.build +++ b/src/bin/initdb/meson.build @@ -21,7 +21,7 @@ initdb = executable('initdb', # shared library from a different PG version. Define # USE_PRIVATE_ENCODING_FUNCS to ensure that that happens. c_args: ['-DUSE_PRIVATE_ENCODING_FUNCS'], - dependencies: [frontend_code, libpq, icu, icu_i18n], + dependencies: [libpq, frontend_code, icu, icu_i18n], kwargs: default_bin_args, ) bin_targets += initdb diff --git a/src/bin/pg_amcheck/meson.build b/src/bin/pg_amcheck/meson.build index 316ea0d40b8..c8f792ff971 100644 --- a/src/bin/pg_amcheck/meson.build +++ b/src/bin/pg_amcheck/meson.build @@ -12,7 +12,7 @@ endif pg_amcheck = executable('pg_amcheck', pg_amcheck_sources, - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args, ) bin_targets += pg_amcheck diff --git a/src/bin/pg_basebackup/meson.build b/src/bin/pg_basebackup/meson.build index 3a7fc10eab0..b85ba465d47 100644 --- a/src/bin/pg_basebackup/meson.build +++ b/src/bin/pg_basebackup/meson.build @@ -7,7 +7,7 @@ common_sources = files( 'walmethods.c', ) -pg_basebackup_deps = [frontend_code, libpq, lz4, zlib, zstd] +pg_basebackup_deps = [libpq, frontend_code, lz4, zlib, zstd] pg_basebackup_common = static_library('libpg_basebackup_common', common_sources, dependencies: pg_basebackup_deps, @@ -45,7 +45,7 @@ endif pg_createsubscriber = executable('pg_createsubscriber', pg_createsubscriber_sources, - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args, ) bin_targets += pg_createsubscriber diff --git a/src/bin/pg_combinebackup/meson.build b/src/bin/pg_combinebackup/meson.build index e80a4756a7f..04e09162d9b 100644 --- a/src/bin/pg_combinebackup/meson.build +++ b/src/bin/pg_combinebackup/meson.build @@ -17,7 +17,7 @@ endif pg_combinebackup = executable('pg_combinebackup', pg_combinebackup_sources, - dependencies: [frontend_code], + dependencies: [libpq, frontend_code], kwargs: default_bin_args, ) bin_targets += pg_combinebackup diff --git a/src/bin/pg_ctl/meson.build b/src/bin/pg_ctl/meson.build index e92ba50f8a3..4f4a977dc0f 100644 --- a/src/bin/pg_ctl/meson.build +++ b/src/bin/pg_ctl/meson.build @@ -12,7 +12,7 @@ endif pg_ctl = executable('pg_ctl', pg_ctl_sources, - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args, ) bin_targets += pg_ctl diff --git a/src/bin/pg_dump/meson.build b/src/bin/pg_dump/meson.build index f3c669f484e..2264ed9faa9 100644 --- a/src/bin/pg_dump/meson.build +++ b/src/bin/pg_dump/meson.build @@ -22,7 +22,7 @@ pg_dump_common_sources = files( pg_dump_common = static_library('libpgdump_common', pg_dump_common_sources, c_pch: pch_postgres_fe_h, - dependencies: [frontend_code, libpq, lz4, zlib, zstd], + dependencies: [libpq, frontend_code, lz4, zlib, zstd], kwargs: internal_lib_args, ) @@ -42,7 +42,7 @@ endif pg_dump = executable('pg_dump', pg_dump_sources, link_with: [pg_dump_common], - dependencies: [frontend_code, libpq, zlib], + dependencies: [libpq, frontend_code, zlib], kwargs: default_bin_args, ) bin_targets += pg_dump @@ -61,7 +61,7 @@ endif pg_dumpall = executable('pg_dumpall', pg_dumpall_sources, link_with: [pg_dump_common], - dependencies: [frontend_code, libpq, zlib], + dependencies: [libpq, frontend_code, zlib], kwargs: default_bin_args, ) bin_targets += pg_dumpall @@ -80,7 +80,7 @@ endif pg_restore = executable('pg_restore', pg_restore_sources, link_with: [pg_dump_common], - dependencies: [frontend_code, libpq, zlib], + dependencies: [libpq, frontend_code, zlib], kwargs: default_bin_args, ) bin_targets += pg_restore diff --git a/src/bin/pg_rewind/meson.build b/src/bin/pg_rewind/meson.build index 97f001d94a5..f241f37673c 100644 --- a/src/bin/pg_rewind/meson.build +++ b/src/bin/pg_rewind/meson.build @@ -21,7 +21,7 @@ endif pg_rewind = executable('pg_rewind', pg_rewind_sources, - dependencies: [frontend_code, libpq, lz4, zstd], + dependencies: [libpq, frontend_code, lz4, zstd], c_args: ['-DFRONTEND'], # needed for xlogreader et al kwargs: default_bin_args, ) diff --git a/src/bin/pg_upgrade/meson.build b/src/bin/pg_upgrade/meson.build index ac992f0d14b..8aefaeea91f 100644 --- a/src/bin/pg_upgrade/meson.build +++ b/src/bin/pg_upgrade/meson.build @@ -28,7 +28,7 @@ endif pg_upgrade = executable('pg_upgrade', pg_upgrade_sources, c_pch: pch_postgres_fe_h, - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args, ) bin_targets += pg_upgrade diff --git a/src/bin/pg_verifybackup/meson.build b/src/bin/pg_verifybackup/meson.build index f45ea790d8e..7aaee24bd79 100644 --- a/src/bin/pg_verifybackup/meson.build +++ b/src/bin/pg_verifybackup/meson.build @@ -13,7 +13,7 @@ endif pg_verifybackup = executable('pg_verifybackup', pg_verifybackup_sources, - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args, ) bin_targets += pg_verifybackup diff --git a/src/bin/pgbench/meson.build b/src/bin/pgbench/meson.build index a2a909a8442..de013cc9827 100644 --- a/src/bin/pgbench/meson.build +++ b/src/bin/pgbench/meson.build @@ -27,7 +27,7 @@ endif pgbench = executable('pgbench', pgbench_sources, - dependencies: [frontend_code, libpq, thread_dep], + dependencies: [libpq, frontend_code, thread_dep], include_directories: include_directories('.'), c_pch: pch_postgres_fe_h, c_args: host_system == 'windows' ? ['-DFD_SETSIZE=1024'] : [], diff --git a/src/bin/psql/meson.build b/src/bin/psql/meson.build index d344053c23b..4749d751aa8 100644 --- a/src/bin/psql/meson.build +++ b/src/bin/psql/meson.build @@ -58,7 +58,7 @@ psql = executable('psql', psql_sources, c_pch: pch_postgres_fe_h, include_directories: include_directories('.'), - dependencies: [frontend_code, libpq, readline], + dependencies: [libpq, frontend_code, readline], kwargs: default_bin_args, ) bin_targets += psql diff --git a/src/bin/scripts/meson.build b/src/bin/scripts/meson.build index a4fed59d1c9..d422ca542f9 100644 --- a/src/bin/scripts/meson.build +++ b/src/bin/scripts/meson.build @@ -2,7 +2,7 @@ scripts_common = static_library('libscripts_common', files('common.c'), - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: internal_lib_args, ) @@ -28,7 +28,7 @@ foreach binary : binaries binary = executable(binary, binary_sources, link_with: [scripts_common], - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args, ) bin_targets += binary @@ -36,7 +36,7 @@ endforeach vacuuming_common = static_library('libvacuuming_common', files('common.c', 'vacuuming.c'), - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: internal_lib_args, ) @@ -55,7 +55,7 @@ foreach binary : binaries binary = executable(binary, binary_sources, link_with: [vacuuming_common], - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args, ) bin_targets += binary diff --git a/src/fe_utils/meson.build b/src/fe_utils/meson.build index ddac3c3a658..0a65b973779 100644 --- a/src/fe_utils/meson.build +++ b/src/fe_utils/meson.build @@ -32,7 +32,7 @@ fe_utils_sources += psqlscan fe_utils = static_library('libpgfeutils', fe_utils_sources, c_pch: pch_postgres_fe_h, - include_directories: [postgres_inc, libpq_inc], + include_directories: [libpq_inc, postgres_inc], c_args: host_system == 'windows' ? ['-DFD_SETSIZE=1024'] : [], dependencies: frontend_common_code, kwargs: default_lib_args, diff --git a/src/interfaces/ecpg/ecpglib/meson.build b/src/interfaces/ecpg/ecpglib/meson.build index 8f478c6a73e..fb7d33d2a0e 100644 --- a/src/interfaces/ecpg/ecpglib/meson.build +++ b/src/interfaces/ecpg/ecpglib/meson.build @@ -30,7 +30,7 @@ ecpglib_st = static_library('libecpg', include_directories: ecpglib_inc, c_args: ecpglib_c_args, c_pch: pch_postgres_fe_h, - dependencies: [frontend_stlib_code, thread_dep, libpq], + dependencies: [libpq, frontend_stlib_code, thread_dep], link_with: [ecpg_pgtypes_st], kwargs: default_lib_args, ) @@ -41,7 +41,7 @@ ecpglib_so = shared_library('libecpg', include_directories: ecpglib_inc, c_args: ecpglib_c_args, c_pch: pch_postgres_fe_h, - dependencies: [frontend_shlib_code, libpq, thread_dep], + dependencies: [libpq, frontend_shlib_code, thread_dep], link_with: ecpg_pgtypes_so, soversion: host_system != 'windows' ? '6' : '', darwin_versions: ['6', '6.' + pg_version_major.to_string()], @@ -58,7 +58,7 @@ pkgconfig.generate( url: pg_url, libraries: ecpglib_so, libraries_private: [frontend_stlib_code, thread_dep], - requires_private: ['libpgtypes', 'libpq'], + requires_private: ['libpq', 'libpgtypes'], ) subdir('po', if_found: libintl) diff --git a/src/interfaces/ecpg/include/meson.build b/src/interfaces/ecpg/include/meson.build index a6541e1a686..133ebe2f11f 100644 --- a/src/interfaces/ecpg/include/meson.build +++ b/src/interfaces/ecpg/include/meson.build @@ -1,6 +1,6 @@ # Copyright (c) 2022-2025, PostgreSQL Global Development Group -ecpg_inc = include_directories('.') +ecpg_inc = [libpq_inc, include_directories('.')] ecpg_conf_keys = [ 'SIZEOF_LONG', diff --git a/src/interfaces/ecpg/test/meson.build b/src/interfaces/ecpg/test/meson.build index 4ccdf9d295a..0d48e035e5a 100644 --- a/src/interfaces/ecpg/test/meson.build +++ b/src/interfaces/ecpg/test/meson.build @@ -20,7 +20,7 @@ pg_regress_ecpg = executable('pg_regress_ecpg', pg_regress_ecpg_sources, c_args: pg_regress_cflags, include_directories: [pg_regress_inc, include_directories('.')], - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args + { 'install': false }, @@ -30,7 +30,7 @@ ecpg_test_dependencies += pg_regress_ecpg # create .c files and executables from .pgc files ecpg_test_exec_kw = { 'c_args': cflags_no_missing_var_decls, - 'dependencies': [frontend_code, libpq], + 'dependencies': [libpq, frontend_code], 'include_directories': [ecpg_inc], 'link_with': [ecpglib_so, ecpg_compat_so, ecpg_pgtypes_so], 'build_by_default': false, diff --git a/src/interfaces/ecpg/test/thread/meson.build b/src/interfaces/ecpg/test/thread/meson.build index 6a6745ce0fc..2c34a611898 100644 --- a/src/interfaces/ecpg/test/thread/meson.build +++ b/src/interfaces/ecpg/test/thread/meson.build @@ -18,6 +18,6 @@ foreach pgc_file : pgc_files ecpg_test_dependencies += executable(pgc_file, exe_input, - kwargs: ecpg_test_exec_kw + {'dependencies': [frontend_code, libpq, thread_dep,]}, + kwargs: ecpg_test_exec_kw + {'dependencies': [libpq, frontend_code, thread_dep,]}, ) endforeach diff --git a/src/interfaces/libpq/test/meson.build b/src/interfaces/libpq/test/meson.build index 07a5facc321..75d2012ba17 100644 --- a/src/interfaces/libpq/test/meson.build +++ b/src/interfaces/libpq/test/meson.build @@ -14,7 +14,7 @@ endif libpq_test_deps += executable('libpq_uri_regress', libpq_uri_regress_sources, - dependencies: [frontend_no_fe_utils_code, libpq], + dependencies: [libpq, frontend_no_fe_utils_code], kwargs: default_bin_args + { 'install': false, } @@ -33,7 +33,7 @@ endif libpq_test_deps += executable('libpq_testclient', libpq_testclient_sources, - dependencies: [frontend_no_fe_utils_code, libpq], + dependencies: [libpq, frontend_no_fe_utils_code], kwargs: default_bin_args + { 'install': false, } diff --git a/src/test/isolation/meson.build b/src/test/isolation/meson.build index a180e4e2741..660b11eff8b 100644 --- a/src/test/isolation/meson.build +++ b/src/test/isolation/meson.build @@ -35,7 +35,7 @@ pg_isolation_regress = executable('pg_isolation_regress', isolation_sources, c_args: pg_regress_cflags, include_directories: pg_regress_inc, - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args + { 'install_dir': dir_pgxs / 'src/test/isolation', }, @@ -52,7 +52,7 @@ endif isolationtester = executable('isolationtester', isolationtester_sources, include_directories: include_directories('.'), - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args + { 'install_dir': dir_pgxs / 'src/test/isolation', }, diff --git a/src/test/modules/libpq_pipeline/meson.build b/src/test/modules/libpq_pipeline/meson.build index 3fd70a04a38..83201111ca3 100644 --- a/src/test/modules/libpq_pipeline/meson.build +++ b/src/test/modules/libpq_pipeline/meson.build @@ -12,7 +12,7 @@ endif libpq_pipeline = executable('libpq_pipeline', libpq_pipeline_sources, - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args + { 'install': false, }, diff --git a/src/test/modules/oauth_validator/meson.build b/src/test/modules/oauth_validator/meson.build index a6f937fd7d7..2cd5c4cd537 100644 --- a/src/test/modules/oauth_validator/meson.build +++ b/src/test/modules/oauth_validator/meson.build @@ -60,7 +60,7 @@ endif oauth_hook_client = executable('oauth_hook_client', oauth_hook_client_sources, - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args + { 'install': false, }, diff --git a/src/test/modules/test_escape/meson.build b/src/test/modules/test_escape/meson.build index a21341d5067..04fd0be0889 100644 --- a/src/test/modules/test_escape/meson.build +++ b/src/test/modules/test_escape/meson.build @@ -10,7 +10,7 @@ endif test_escape = executable('test_escape', test_escape_sources, - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args + { 'install': false, } diff --git a/src/test/modules/test_int128/meson.build b/src/test/modules/test_int128/meson.build index 4c2be7a0326..94bca2edc5c 100644 --- a/src/test/modules/test_int128/meson.build +++ b/src/test/modules/test_int128/meson.build @@ -12,7 +12,7 @@ endif test_int128 = executable('test_int128', test_int128_sources, - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args + { 'install': false, }, diff --git a/src/test/modules/test_json_parser/meson.build b/src/test/modules/test_json_parser/meson.build index 5672045f496..2c6031a14df 100644 --- a/src/test/modules/test_json_parser/meson.build +++ b/src/test/modules/test_json_parser/meson.build @@ -23,7 +23,7 @@ test_json_parser_incremental = executable('test_json_parser_incremental', # the shared-library flavor of jsonapi. test_json_parser_incremental_shlib = executable('test_json_parser_incremental_shlib', test_json_parser_incremental_sources, - dependencies: [frontend_shlib_code, libpq], + dependencies: [libpq, frontend_shlib_code], c_args: ['-DJSONAPI_SHLIB_ALLOC'], link_with: [common_excluded_shlib], kwargs: default_bin_args + { diff --git a/src/test/modules/test_oat_hooks/meson.build b/src/test/modules/test_oat_hooks/meson.build index 1e600b0f4c7..6f0c4afd433 100644 --- a/src/test/modules/test_oat_hooks/meson.build +++ b/src/test/modules/test_oat_hooks/meson.build @@ -12,7 +12,9 @@ endif test_oat_hooks = shared_module('test_oat_hooks', test_oat_hooks_sources, - kwargs: pg_test_mod_args, + kwargs: pg_test_mod_args + { + 'dependencies': [libpq] + pg_test_mod_args['dependencies'], + } ) test_install_libs += test_oat_hooks diff --git a/src/test/regress/meson.build b/src/test/regress/meson.build index 1da9e9462a9..99f402f49a8 100644 --- a/src/test/regress/meson.build +++ b/src/test/regress/meson.build @@ -2,7 +2,7 @@ # also used by isolationtester and ecpg tests pg_regress_c = files('pg_regress.c') -pg_regress_inc = include_directories('.') +pg_regress_inc = [libpq_inc, include_directories('.')] regress_sources = pg_regress_c + files( 'pg_regress_main.c' @@ -30,7 +30,7 @@ endif pg_regress = executable('pg_regress', regress_sources, c_args: pg_regress_cflags, - dependencies: [frontend_code, libpq], + dependencies: [libpq, frontend_code], kwargs: default_bin_args + { 'install_dir': dir_pgxs / 'src/test/regress', }, -- 2.51.1
From 23df76b10985b3624a71e9357b98a6cccf377542 Mon Sep 17 00:00:00 2001 From: Thomas Munro <[email protected]> Date: Mon, 3 Nov 2025 11:32:57 +1300 Subject: [PATCH v3 2/2] ci: Test include path order with decoy libpq-fe.h. If the configure or meson scripts would allow headers from a copy of libpq installed under --with-includes or -Dextra_include_dirs to be found before the in-tree copy we need, then this canary header will raise an error. This problem has bitten us in both build systems, but often goes unnoticed until libpq-fe.h changes incompatibly and someone with an affected system notices. This test would cause CI to fail fast. Also add missing set -e to the shell scripts run under su, since otherwise the build step would confusingly succeed. Discussion: https://postgr.es/m/CA%2BhUKG%2Bx-cys30%3D7L2B8%3DcZ%2B-z6QDOj-oQy9O3CnkeXnrnm3OQ%40mail.gmail.com --- .cirrus.tasks.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.cirrus.tasks.yml b/.cirrus.tasks.yml index f2581cfb2e5..3df6de6acd9 100644 --- a/.cirrus.tasks.yml +++ b/.cirrus.tasks.yml @@ -424,6 +424,8 @@ task: CCACHE_DIR: /tmp/ccache_dir DEBUGINFOD_URLS: "https://debuginfod.debian.net" + POISONED_HEADERS: /tmp/poisoned_headers + # Enable a reasonable set of sanitizers. Use the linux task for that, as # it's one of the fastest tasks (without sanitizers). Also several of the # sanitizers work best on linux. @@ -492,11 +494,24 @@ task: #apt-get update #DEBIAN_FRONTEND=noninteractive apt-get -y install ... + # Detect mistakes that would allow unwanted headers from outside our tree be + # found with --with-includes or -Dextra_include_dirs. That is primarily a + # risk on non-Linux systems that install packages under eg /usr/local that + # must be explicitly added to the header search path, but this is a + # convenient place to test both build systems. + setup_poisoned_headers_script: | + for header in "libpq-fe.h" "libpq/libpq-fe.h" ; do + mkdir -p "${POISONED_HEADERS}/$(dirname $header)" + echo '#error "external header hides in-tree header"' \ + > "${POISONED_HEADERS}/$header" + done + matrix: # SPECIAL: # - Uses address sanitizer, sanitizer failures are typically printed in # the server log # - Configures postgres with a small segment size + # - Poisoned headers in search path - name: Linux - Debian Bookworm - Autoconf env: @@ -517,6 +532,7 @@ task: --with-segsize-blocks=6 \ --with-libnuma \ --with-liburing \ + --with-includes="${POISONED_HEADERS}" \ \ ${LINUX_CONFIGURE_FEATURES} \ \ @@ -540,6 +556,7 @@ task: # - Test both 64bit and 32 bit builds # - uses io_method=io_uring # - Uses meson feature autodetection + # - Poisoned headers in search path - name: Linux - Debian Bookworm - Meson env: @@ -552,6 +569,7 @@ task: su postgres <<-EOF meson setup \ ${MESON_COMMON_PG_CONFIG_ARGS} \ + -Dextra_include_dirs="${POISONED_HEADERS}" \ --buildtype=debug \ ${LINUX_MESON_FEATURES} -Dllvm=enabled \ build @@ -564,6 +582,7 @@ task: export CC='ccache gcc -m32' meson setup \ ${MESON_COMMON_PG_CONFIG_ARGS} \ + -Dextra_include_dirs="${POISONED_HEADERS}" \ --buildtype=debug \ --pkg-config-path /usr/lib/i386-linux-gnu/pkgconfig/ \ -DPERL=perl5.36-i386-linux-gnu \ @@ -573,12 +592,14 @@ task: build_script: | su postgres <<-EOF + set -e ninja -C build -j${BUILD_JOBS} ${MBUILD_TARGET} ninja -C build -t missingdeps EOF build_32_script: | su postgres <<-EOF + set -e ninja -C build-32 -j${BUILD_JOBS} ${MBUILD_TARGET} ninja -C build -t missingdeps EOF -- 2.51.1
