Headerscheck support for meson

Started by Zsolt Parragiabout 2 months ago10 messageshackers
Jump to latest
#1Zsolt Parragi
zsolt.parragi@percona.com

Hello

While working on a similar script I noticed that we do not run
headerscheck as part of the meson test suite, and that some required
settings in Makefile.global aren't populated properly with meson.

The attached patch solves both issues.

Attachments:

0001-Add-headerscheck-support-for-meson.patchapplication/octet-stream; name=0001-Add-headerscheck-support-for-meson.patchDownload+84-6
#2Nazir Bilal Yavuz
byavuz81@gmail.com
In reply to: Zsolt Parragi (#1)
Re: Headerscheck support for meson

Hi,

Thank you for working on this!

On Tue, 17 Feb 2026 at 18:15, Zsolt Parragi <zsolt.parragi@percona.com> wrote:

Hello

While working on a similar script I noticed that we do not run
headerscheck as part of the meson test suite, and that some required
settings in Makefile.global aren't populated properly with meson.

The attached patch solves both issues.

I didn't study the patch yet but there is another thread which
implements the headerscheck [1]/messages/by-id/CAMSWrt-PoQt4sHryWrB1ViuGBJF_PpbjoSGrWR2Ry47bHNLDqg@mail.gmail.com. You might want to check it out.

[1]: /messages/by-id/CAMSWrt-PoQt4sHryWrB1ViuGBJF_PpbjoSGrWR2Ry47bHNLDqg@mail.gmail.com

--
Regards,
Nazir Bilal Yavuz
Microsoft

#3Zsolt Parragi
zsolt.parragi@percona.com
In reply to: Nazir Bilal Yavuz (#2)
Re: Headerscheck support for meson

Oops, sorry, somehow I missed that thread when I searched for this.

The main difference seems to be that I added this as part of the test
suite and not the build, and I didn't had to modify headerscheck
itself - at least it works on my test setups without modification.

#4Andres Freund
andres@anarazel.de
In reply to: Zsolt Parragi (#3)
Re: Headerscheck support for meson

Hi,

On 2026-02-17 15:48:50 +0000, Zsolt Parragi wrote:

Oops, sorry, somehow I missed that thread when I searched for this.

The main difference seems to be that I added this as part of the test
suite and not the build, and I didn't had to modify headerscheck
itself - at least it works on my test setups without modification.

I'm not sure stuff like this is really well suited to be done via tests.

My personal distinction is that there should be a benefit for tests to be run
over and over, regardless of source code changes, because the tests might fail
only occasionally. Whereas e.g. headerscheck will either fail or succeed,
rerunning it without source code changes should never change the result.

headerscheck also has the habit of failing on some platforms, it'll e.g. not
work on windows when building with msvc and probably won't work when building
with mingw.

I also think that eventually we should do what you alluded to in a comment,
namely make headerscheck an explicit part of the build system, with proper
support for dependencies and parallelism.

Until then I'd just make it a target that needs to be run explicitly.

I guess a next step after that could be for headerscheck to grow the ability
to output dependencies. Once you have that, having run headerscheck could
create a stamp file. Then the headerscheck target would only need to do work
if either the stamp file is not present (i.e. the first run) or if one of the
tested headers changes.

Greetings,

Andres Freund

#5Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Andres Freund (#4)
Re: Headerscheck support for meson

On 2026-Feb-17, Andres Freund wrote:

I also think that eventually we should do what you alluded to in a comment,
namely make headerscheck an explicit part of the build system, with proper
support for dependencies and parallelism.

How would that work? I imagine that there would be a script or program
that takes a single .h file as argument and returns OK or fail for it;
then meson knows to run that script once for every .h file in the tree.

How to construct the list of files might also be a separate simple
script that just does "git ls-files *.h" then filters out the files we
know can't pass the compile.

Would it make sense to split our current script into a bunch of smaller
ones that each does one of these things, so that they can be reused by
a Meson target in a way that's more convenient? In Make we would just
call some wrapper script that simply calls the others to do the full job
in a single pass, the way it is now.

--
Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/
"Always assume the user will do much worse than the stupidest thing
you can imagine." (Julien PUYDT)

#6Zsolt Parragi
zsolt.parragi@percona.com
In reply to: Andres Freund (#4)
Re: Headerscheck support for meson

My idea was to generate simple source files for each header in the
build directory, and then include everything into one or more static
libraries. The tricky part could be handling generated headers, but I
think that shouldn't be too much of a problem.

Originally I decided against this version because I thought that I had
to somehow duplicate the list of special cases, but now I realized
that I could refactor the list of special files into a separate file
that gets loaded by both meson and the bash script - I'll look at this
approach once more, maybe it will work.

#7Zsolt Parragi
zsolt.parragi@percona.com
In reply to: Zsolt Parragi (#6)
Re: Headerscheck support for meson

Hello

See attached v2, which uses a meson-integrated version while only
duplicating some of the code (and adding some python scripts).

It uses static libraries, at first I tried to exclude it from the
default build and add it as a test dependency, so it only gets built
as part of `meson test` (but only once).

I had multiple problems with this:

* Meson before 1.7 ignores this and builds it anyway
* Doing it in 2 steps is significantly slower than everything
together, I guess it's better if the minimal work and real work
compilations get mixed together.

On my laptop, meson build time went from ~7 seconds to ~10 seconds
with headerscheck enabled, and I didn't see any difference in
configuration time. I also added a configuration flag for it in case
somebody wants to disable it, or if it's slower in other environments,
but it is enabled by default.

The header-guessing part is duplicated instead of using a common
configuration file as that seemed smaller overall. The python code is
a bit uglier because it uses chained ifs - I'm not sure what's the
minimum python version the postgres builds officially requires? The
current meson version depends only on 3.6, so I didn't want to use
pattern matching.

Compared to headerscheck, this build can't use -fsyntax-only because
meson needs build artifacts - but those are basically empty, so it
shouldn't matter that much. And thanks to ninja, it's parallel!

What do you think?

Attachments:

v2-0001-Integrate-headerscheck-into-the-meson-build.patchapplication/octet-stream; name=v2-0001-Integrate-headerscheck-into-the-meson-build.patchDownload+459-116
#8Andres Freund
andres@anarazel.de
In reply to: Alvaro Herrera (#5)
Re: Headerscheck support for meson

Hi,

On 2026-02-17 18:40:59 +0100, Álvaro Herrera wrote:

On 2026-Feb-17, Andres Freund wrote:

I also think that eventually we should do what you alluded to in a comment,
namely make headerscheck an explicit part of the build system, with proper
support for dependencies and parallelism.

How would that work? I imagine that there would be a script or program
that takes a single .h file as argument and returns OK or fail for it;
then meson knows to run that script once for every .h file in the tree.

Something like that, yes.

Instead of generating a .c file to include the .h, I'd probably try to go for
something like

${CC|CXX} ... -fsyntax-only -include {postgres.h|c.h|postgres_fe.h} -include header/to/test.h

so that we don't have to generate a gazillion files.

How to construct the list of files might also be a separate simple
script that just does "git ls-files *.h" then filters out the files we
know can't pass the compile.

One disadvantage with doing something like git ls-files at configure is that
meson can't know to rerun that when a new header is added. That's probably
not a huge issue, but worth thinking about.

I have wondered if we should just make it an explicit list of headers that are
to be installed in the source tree that could then be used by both meson/make
install and things like headerscheck. But it might be too much of a pain.

I also wonder if we should deal with things like files known to not be C++
safe by putting some annotation in the header, rather than tracking that in a
script? Might also be used to actually output a more readable error message if
somebody were to include such a header from c++.

Would it make sense to split our current script into a bunch of smaller
ones that each does one of these things, so that they can be reused by
a Meson target in a way that's more convenient? In Make we would just
call some wrapper script that simply calls the others to do the full job
in a single pass, the way it is now.

Yes.

Greetings,

Andres Freund

#9Andreas Karlsson
andreas.karlsson@percona.com
In reply to: Zsolt Parragi (#7)
Re: Headerscheck support for meson

On 2/18/26 11:11 PM, Zsolt Parragi wrote:

See attached v2, which uses a meson-integrated version while only
duplicating some of the code (and adding some python scripts).

Is the plan to use the Python scripts also in the Autotools build? E.g.
by calling them from the bash script?

It uses static libraries, at first I tried to exclude it from the
default build and add it as a test dependency, so it only gets built
as part of `meson test` (but only once).

I feel this could add a substantial performance hit compared to the
shell script which uses -fsyntax-only, or am I wrong? Also -Wall seems
to be missing.

* Meson before 1.7 ignores this and builds it anyway

Any idea why? Because this sounds like a potential showstopper since
Meson 1.7 is rather new.

The header-guessing part is duplicated instead of using a common
configuration file as that seemed smaller overall. The python code is
a bit uglier because it uses chained ifs - I'm not sure what's the
minimum python version the postgres builds officially requires? The
current meson version depends only on 3.6, so I didn't want to use
pattern matching.

It would be nice if the guessing was moved the config file too, or if
the shell script called out to the Python scripts. I am not a fan of
this duplication.

Another note: there is a mess where some scripts are now called
"headercheck" while others "headerscheck". We should pick one.

Andreas

#10Zsolt Parragi
zsolt.parragi@percona.com
In reply to: Andreas Karlsson (#9)
Re: Headerscheck support for meson

On Wed, Feb 18, 2026 at 11:24 PM Andres Freund <andres@anarazel.de> wrote:

Instead of generating a .c file to include the .h, I'd probably try to go for
something like

${CC|CXX} ... -fsyntax-only -include {postgres.h|c.h|postgres_fe.h} -include header/to/test.h

so that we don't have to generate a gazillion files.

I don't think we can do this without a gazillion files:

1. If you mean using per file custom_targets like the meson bitcode
patch, that would still require generating stamp files for each
execution, so all we would do is to replace the currently empty object
files with similarly sized stamp files
2. Testing that a header compiles in C++ mode requires adding an
extern C block around the include, so "-include" can't be used. I can
work around that by adding a block such as:

extern "C" {
#include FILENAME_MACRO
}

And a -DFILENAME_MACRO=... flag to the compiler.

But I still have to add ~1400 custom targets to meson, and handle the
compiler flag setup manually instead of the currently automated way
with the static library. I'm not sure if the additional complexity of
the implementation is worth it for this, I don't think we would see
any significant execution time difference.

One disadvantage with doing something like git ls-files at configure is that
meson can't know to rerun that when a new header is added. That's probably
not a huge issue, but worth thinking about.

I have wondered if we should just make it an explicit list of headers that are
to be installed in the source tree that could then be used by both meson/make
install and things like headerscheck. But it might be too much of a pain.

Headerscheck currently also checks internal not installed headers, and
skips installed but generated headers. Should we change these rules?

We also shouldn't add the extensions in contrib into the "main" list,
so that adds a bit of complexity if we somehow want to integrate those
into headerscheck, I'll have to think about that part.

(Otherwise this doesn't sounds like a pain, and would be good practice
to use explicit lists instead of globs for installing files, I'll look
into that)

I also wonder if we should deal with things like files known to not be C++
safe by putting some annotation in the header, rather than tracking that in a
script? Might also be used to actually output a more readable error message if
somebody were to include such a header from c++.

Also sounds like a good idea, but kind of an independent patch with ifdefs.

On Wed, Feb 18, 2026 at 11:35 PM Andreas Karlsson <andreas@proxel.se> wrote:

Is the plan to use the Python scripts also in the Autotools build? E.g.
by calling them from the bash script?

Are we ok with adding a python dependency to the autotools build? I
used python for the new script because meson already depends on it,
but I don't think make does.

I feel this could add a substantial performance hit compared to the
shell script which uses -fsyntax-only, or am I wrong? Also -Wall seems
to be missing.

Wall is already added by the meson build, we use exactly the same
configuration flags as for the rest of the build, that's the advantage
of using a static library. "-fsyntax-only" saves only ~2% time vs
generating an empty object file in my benchmarks, and the parallel
ninja execution is several times faster than the bash script, so I
don't think this is a significant difference.

* Meson before 1.7 ignores this and builds it anyway

Any idea why? Because this sounds like a potential showstopper since
Meson 1.7 is rather new.

I'm using a different approach, so this doesn't affect the patch now.