meson: pass OpenSSL/ICU include dirs to extensions

Started by Aidar Imamov1 day ago2 messageshackers
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

appliessuccessCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t253717
psql -h localhost -U postgres

Built from patchset v1 (message #1), September 09, 2026 at 07:48 PM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t253717_1 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t253717_1 && git checkout t253717_1

Patchset v1 (message #1) is on t253717_1

Jump to latest
#1Aidar Imamov
imamovaj22@gmail.com

Hi,

I was building an extension against a meson-built tree on macOS and the
build failed because a public server header includes openssl/ssl.h, but
the compiler couldn't find it. The extension includes libpq/auth.h,
which pulls in libpq-be.h, which includes openssl/ssl.h when OpenSSL
support is enabled. On systems where OpenSSL is installed in a
non-default prefix (Homebrew on macOS being the common case), that header
is not on the default search path.

With autoconf this works because you pass the include path to configure
via CPPFLAGS and it ends up in Makefile.global and pg_config --cppflags.
But meson keeps the include directory inside the ssl dependency object
and never writes it into var_cppflags, so extensions get nothing.

ICU has the same issue, and it's actually been known since the original
meson commit: ICU_CFLAGS sits in pgxs_empty with a comment saying it
"needs to be added, included by public server headers", so the
$(ICU_CFLAGS) reference in Makefile.global has always been empty.

The attached patch fixes both, mirroring how autoconf handles each.

For OpenSSL I extract the include directory from the ssl dependency and
append it to var_cppflags in src/include/meson.build. Since var_cppflags
feeds both VAL_CPPFLAGS and CPPFLAGS in the generated Makefile.global,
this fixes pg_config --cppflags and the PGXS build in one place, which
matches autoconf (where OpenSSL rides along in CPPFLAGS).

For ICU I populate ICU_CFLAGS from the icu dependency and drop it from
pgxs_empty. ICU gets a cmake fallback in get_variable because the meson
setup can find ICU via cmake; OpenSSL can't, so it doesn't get one.

One thing I noticed and left alone: autoconf's pg_config --cppflags also
includes ICU_CFLAGS (VAL_CPPFLAGS is built from STD_CPPFLAGS, which picks
up the override), while meson's won't. Extensions don't care because they
get ICU through $(ICU_CFLAGS) in Makefile.global, and I didn't want to
duplicate the flags in the PGXS path. Easy to add ICU to var_cppflags
too if you want full parity there.

I tested by building and installing PostgreSQL both ways (autoconf and
meson, with SSL enabled, on macOS with Homebrew) and compiling the same
extension against each installation. Both build now, and the compile
command contains both the OpenSSL and ICU include directories. Before
the patch, meson's pg_config --cppflags was empty for these.

Regards,
Aidar Imamov

Attachments:

t253717_1
0001-meson_expose-openssl_and_icu_include_dirs.patchapplication/octet-stream; name=0001-meson_expose-openssl_and_icu_include_dirs.patch; x-unix-mode=0644Download+33-4
#2Grigorev Jurij
ju.grigorev@ftdata.ru
In reply to: Aidar Imamov (#1)
Re: [MASSMAIL]meson: pass OpenSSL/ICU include dirs to extensions

Hi,

On Tue, Sep 08, 2026 at 07:37:01PM +0000, Aidar Imamov wrote:

Some external dependencies have headers that are included by public
server headers (e.g. libpq-be.h includes openssl/ssl.h).

Thanks for picking this up! The problem is real, and the ICU half of
it has been sitting there since the Meson PGXS layer went in -- the
ICU_CFLAGS entry in pgxs_empty even carries a comment saying it still
needs to be done.

I do have some questions about how the include flags are extracted.
None of them are about the direction, which I think is right.

The main one is about
dependency.get_variable(pkgconfig: 'includedir'). That gives us the
raw pkg-config variable rather than the compiler arguments Meson
itself used for the dependency, and the two need not be equivalent: there may
be several include directories, or flags that aren't a plain
-I<includedir>, or, in a cross build, paths where
PKG_CONFIG_SYSROOT_DIR may not be applied to the raw includedir value
in the same way as to the compiler flags.

I looked for a way to take the flags directly instead. LLVM does
something along those lines, reading cxxflags from llvm-config rather
than rebuilding -I from a directory, but pkg-config does not seem to
expose Cflags through get_variable() in the same way, so this probably
needs a different approach. I don't have a good suggestion yet.

The ICU CMake fallback shows the difficulty concretely:

icu_incdir.split(';')[0]

ICU_INCLUDE_DIRS can hold more than one directory, so I think we would
want to keep all of them rather than just the first.

The OpenSSL part also appears not to cover the CMake discovery method.
In that case

ssl.get_variable(pkgconfig: 'includedir', default_value: '')

falls back to the empty default, even though the dependency may well
have non-default include directories. The cc.find_library() path is a
different situation, and extra_include_dirs never reaching
var_cppflags is really a broader PGXS gap rather than something for
this patch. It would help me to know which discovery methods you are
aiming to cover.

A much smaller thing: '-I' concatenated with a raw directory may need
escaping before it lands in Makefile.global, in case the prefix
contains whitespace or characters that mean something to make or the
shell.

For what it's worth, I agree with putting OpenSSL in CPPFLAGS and ICU
in ICU_CFLAGS. That matches how Makefile.global is structured, and it
might be worth spelling out in the commit message, since it is not
obvious why the two are handled differently.

Would an automated check of the generated PGXS flags be feasible, with
the dependency in a non-default prefix?

Mostly this comes back to one thing: having the flags follow what
Meson actually used for the dependency, instead of rebuilding them
from a directory variable. If a next version does that and keeps all
the include directories, I think the approach is sound. Happy to look
again whenever you have something!

Thanks,
Yuriy Grigoryev
________________________________________
От: Aidar Imamov <imamovaj22@gmail.com>
Отправлено: 9 сентября 2026 г. 2:37:01
Кому: pgsql-hackers@postgresql.org
Тема: [MASSMAIL]meson: pass OpenSSL/ICU include dirs to extensions

Hi,

I was building an extension against a meson-built tree on macOS and the
build failed because a public server header includes openssl/ssl.h, but
the compiler couldn't find it. The extension includes libpq/auth.h,
which pulls in libpq-be.h, which includes openssl/ssl.h when OpenSSL
support is enabled. On systems where OpenSSL is installed in a
non-default prefix (Homebrew on macOS being the common case), that header
is not on the default search path.

With autoconf this works because you pass the include path to configure
via CPPFLAGS and it ends up in Makefile.global and pg_config --cppflags.
But meson keeps the include directory inside the ssl dependency object
and never writes it into var_cppflags, so extensions get nothing.

ICU has the same issue, and it's actually been known since the original
meson commit: ICU_CFLAGS sits in pgxs_empty with a comment saying it
"needs to be added, included by public server headers", so the
$(ICU_CFLAGS) reference in Makefile.global has always been empty.

The attached patch fixes both, mirroring how autoconf handles each.

For OpenSSL I extract the include directory from the ssl dependency and
append it to var_cppflags in src/include/meson.build. Since var_cppflags
feeds both VAL_CPPFLAGS and CPPFLAGS in the generated Makefile.global,
this fixes pg_config --cppflags and the PGXS build in one place, which
matches autoconf (where OpenSSL rides along in CPPFLAGS).

For ICU I populate ICU_CFLAGS from the icu dependency and drop it from
pgxs_empty. ICU gets a cmake fallback in get_variable because the meson
setup can find ICU via cmake; OpenSSL can't, so it doesn't get one.

One thing I noticed and left alone: autoconf's pg_config --cppflags also
includes ICU_CFLAGS (VAL_CPPFLAGS is built from STD_CPPFLAGS, which picks
up the override), while meson's won't. Extensions don't care because they
get ICU through $(ICU_CFLAGS) in Makefile.global, and I didn't want to
duplicate the flags in the PGXS path. Easy to add ICU to var_cppflags
too if you want full parity there.

I tested by building and installing PostgreSQL both ways (autoconf and
meson, with SSL enabled, on macOS with Homebrew) and compiling the same
extension against each installation. Both build now, and the compile
command contains both the OpenSSL and ICU include directories. Before
the patch, meson's pg_config --cppflags was empty for these.

Regards,
Aidar Imamov