Re: meson's in-tree libpq header search order vs -Dextra_include_dirs

From: "Tristan Partin" <tristan(at)partin(dot)io>
To: "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: "Thomas Munro" <thomas(dot)munro(at)gmail(dot)com>, "pgsql-hackers" <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: meson's in-tree libpq header search order vs -Dextra_include_dirs
Date: 2025-11-04 06:17:45
Message-ID: DDZOWJZIJQ4W.1BSCGWFSAJDK6@partin.io
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Mon Nov 3, 2025 at 12:14 AM CST, Tom Lane wrote:
> "Tristan Partin" <tristan(at)partin(dot)io> writes:
>> What is the benefit of -Dextra_include_dirs when you could use -Dc_flags
>> or CFLAGS to specify extra include directories? If you tried either of
>> those as an alternative, would they fix the issue? The existence of the
>> option goes all the way back to the initial commit of the meson port, so
>> I presume it exists to mirror --with-includes, but why does that exist?
>
> --with-includes, and likewise --with-libs, exist because there are
> platforms that require it. For example, on pretty much any
> BSD-derived system, the core /usr/include and /usr/lib files are very
> limited and you'll need to point at places like /usr/pkg/include or
> /opt/local/include or whatever to pull in non-core packages.
>
> I see your point about putting -I flags into CFLAGS, but what you
> are missing is that the order of these flags is unbelievably critical,
> so "just shove it into CFLAGS" is a recipe for failure, especially
> if you haven't even stopped to think about which end to add it at.
> We've learned over decades of trial-and-error with the makefile system
> that treating -I and -L flags specially is more reliable. (See for
> example all the logic in our autoconf scripts to forcibly separate
> -I and -L out of sources like pkg-config. Tracing that stuff back to
> the originating commits and mail discussions would be a constructive
> learning exercise.)

I'm well aware of ordering dependencies, and how annoying they can be.
The perils of C will outlive us all! Given your message and Thomas's
patch, I decided to take a look at the autotools build on PG 16 (since
that is what I had checked out, but maybe also maybe useful as the
original Meson build) and how it compared. Thomas has this hunk in his
patch:

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',
},

Taking a look, specifically, at isolationtester, I get the following
final compilation line for isolationtester.o (please forgive the macOS garbage):

gcc -Wall -Wmissing-prototypes -Wpointer-arith \
-Wdeclaration-after-statement -Werror=vla \
-Werror=unguarded-availability-new -Wendif-labels \
-Wmissing-format-attribute -Wcast-function-type \
-Wformat-security -fno-strict-aliasing -fwrapv \
-fexcess-precision=standard -Wno-unused-command-line-argument \
-Wno-compound-token-split-by-macro -Wno-format-truncation \
-Wno-cast-function-type-strict -O2 -I. \
-I/Users/tristan.partin/Projects/work/postgres/build-autotools/../src/test/isolation \
-I/Users/tristan.partin/Projects/work/postgres/build-autotools/../src/interfaces/libpq \
-I/Users/tristan.partin/Projects/work/postgres/build-autotools/../src/test/isolation/../regress \
-I../../../src/include \
-I/Users/tristan.partin/Projects/work/postgres/build-autotools/../src/include \
-isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX26.0.sdk \
-c -o isolationtester.o \
/Users/tristan.partin/Projects/work/postgres/build-autotools/../src/test/isolation/isolationtester.c

The first include directory that isn't the source or build directory is
the in-tree libpq headers. I assume that is controlled by:

override CPPFLAGS := -I. -I$(srcdir) -I$(libpq_srcdir) \
-I$(srcdir)/../regress $(CPPFLAGS)

Thomas's patch seemingly makes the meson build equivalent to the
autotools build. Just for good measure, following --with-includes, the
include directories in that configure argument end up in CPPFLAGS:

CPPFLAGS="$CPPFLAGS $INCLUDES"

where INCLUDES is:

#
# Include directories
#
ac_save_IFS=$IFS
IFS="${IFS}${PATH_SEPARATOR}"
# SRCH_INC comes from the template file
for dir in $with_includes $SRCH_INC; do
if test -d "$dir"; then
INCLUDES="$INCLUDES -I$dir"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Include directory $dir does not exist." >&5
$as_echo "$as_me: WARNING: *** Include directory $dir does not exist." >&2;}
fi
done
IFS=$ac_save_IFS

From my perspective, it looks like the autotools build has just been
_lucky_ to avoid this problem. I don't see anything that inherently
prevents the problem that Thomas ran into. In my opinion Thomas's patch
is just a parity patch. It's incredible that it took this long to find.

--
Tristan Partin
Databricks (https://databricks.com)

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message shveta malik 2025-11-04 06:23:34 Re: Improve pg_sync_replication_slots() to wait for primary to advance
Previous Message jian he 2025-11-04 06:02:14 Re: CAST(... ON DEFAULT) - WIP build on top of Error-Safe User Functions