diff mbox series

[v2,3/4] meson: add support for 'hdr-check'

Message ID 20250410-505-wire-up-sparse-via-meson-v2-3-acb45cc8a2e5@gmail.com (mailing list archive)
State Superseded
Headers show
Series meson: add corresponding target for Makefile's hdr-check | expand

Commit Message

Karthik Nayak April 10, 2025, 11:30 a.m. UTC
The Makefile supports a target called 'hdr-check', which checks if
individual header files can be independently compiled. Let's port this
functionality to meson, our new build system too. The implementation
resembles that of the Makefile and provides the same check.

Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 meson.build | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 107 insertions(+)

Comments

Phillip Wood April 10, 2025, 2:50 p.m. UTC | #1
Hi Karthik

On 10/04/2025 12:30, Karthik Nayak wrote:
> The Makefile supports a target called 'hdr-check', which checks if
> individual header files can be independently compiled. Let's port this
> functionality to meson, our new build system too. The implementation
> resembles that of the Makefile and provides the same check.

Thanks for adding this, I've left a few comments below

> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
> ---
>   meson.build | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 107 insertions(+)
> 
> diff --git a/meson.build b/meson.build
> index 790d178007..6fce1aa618 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -655,6 +655,12 @@ if git.found()
>     endforeach
>   endif
>   
> +headers_generated = [

To me "generated_headers" would be a more natural name and would match 
the style of "coccinelle_headers" from patch 1 as well as the equivalent 
in the Makefile.

> +  'command-list.h',
> +  'config-list.h',
> +  'hook-list.h'
> +]
> +
>   if not get_option('breaking_changes')
>     builtin_sources += 'builtin/pack-redundant.c'
>   endif
> @@ -1995,6 +2001,107 @@ endif
>   
>   subdir('contrib')
>   
> +headers_check_exclude = headers_generated
> +headers_check_exclude += [
> +  'compat/apple-common-crypto.h',
> +  'compat/bswap.h',
> +  'compat/compiler.h',
> +  'compat/disk.h',
> +  'compat/fsmonitor/fsm-darwin-gcc.h',
> +  'compat/fsmonitor/fsm-health.h',
> +  'compat/fsmonitor/fsm-listen.h',
> +  'compat/mingw.h',
> +  'compat/msvc.h',
> +  'compat/nedmalloc/malloc.c.h',
> +  'compat/nedmalloc/nedmalloc.h',
> +  'compat/nonblock.h',
> +  'compat/obstack.h',
> +  'compat/poll/poll.h',
> +  'compat/precompose_utf8.h',
> +  'compat/regex/regex.h',
> +  'compat/regex/regex_internal.h',
> +  'compat/sha1-chunked.h',
> +  'compat/terminal.h',
> +  'compat/vcbuild/include/sys/param.h',
> +  'compat/vcbuild/include/sys/time.h',
> +  'compat/vcbuild/include/sys/utime.h',
> +  'compat/vcbuild/include/unistd.h',
> +  'compat/vcbuild/include/utime.h',
> +  'compat/win32.h',
> +  'compat/win32/alloca.h',
> +  'compat/win32/dirent.h',
> +  'compat/win32/lazyload.h',
> +  'compat/win32/path-utils.h',
> +  'compat/win32/pthread.h',
> +  'compat/win32/syslog.h',
> +  'compat/zlib-compat.h',
> +  't/unit-tests/clar/clar.h',
> +  't/unit-tests/clar/clar/fixtures.h',
> +  't/unit-tests/clar/clar/fs.h',
> +  't/unit-tests/clar/clar/print.h',
> +  't/unit-tests/clar/clar/sandbox.h',
> +  't/unit-tests/clar/clar/summary.h',
> +  't/unit-tests/clar/test/clar_test.h',
> +  'unicode-width.h',
> +  'xdiff/xdiff.h',
> +  'xdiff/xdiffi.h',
> +  'xdiff/xemit.h',
> +  'xdiff/xinclude.h',
> +  'xdiff/xmacros.h',
> +  'xdiff/xprepare.h',
> +  'xdiff/xtypes.h',
> +  'xdiff/xutils.h',
> +]

Having to manually maintain this list is a bit of a shame as every time 
a new file is added to compat we need to add it to meson.build twice. 
The Makefile avoids this by filtering the list of headers used when 
building git based on their path - can we do the same here?

> +if sha1_backend != 'openssl'
> +  headers_check_exclude += 'sha1/openssl.h'
> +endif
> +if sha256_backend != 'openssl'
> +  headers_check_exclude += 'sha256/openssl.h'
> +endif
> +if sha256_backend != 'nettle'
> +  headers_check_exclude += 'sha256/nettle.h'
> +endif
> +if sha256_backend != 'gcrpyt'
> +  headers_check_exclude += 'sha256/gcrypt.h'
> +endif
> +
> +if headers.length() != 0 and compiler.get_argument_syntax() == 'gcc'
> +  hco_targets = []
> +  foreach h : headers
> +    if headers_check_exclude.contains(h)
> +      continue
> +    endif
> +
> +    hcc = custom_target(
> +      input: h,
> +      output: h.underscorify() + 'cc',
> +      command: [
> +        shell,
> +        '-c',
> +        'echo \'#include "git-compat-util.h"\' > @OUTPUT@ && echo -n \'#include "' + h + '"\' >> @OUTPUT@'

This line is rather long. Also do we really need "echo -n" here, the 
Makefile does not use it.

> +      ]
> +    )
> +
> +    hco = custom_target(
> +      input: hcc,
> +      output: h.underscorify().replace('.h', '.hco'),
> +      command: [
> +        compiler.cmd_array(),
> +        libgit_c_args,
> +        '-I', meson.project_source_root(),
> +        '-I', meson.project_source_root() / 't/unit-tests',

Do you know why we don't need to add these include paths for the 
equivalent rule in the Makefile?

Thanks

Phillip

> +        '-o', '/dev/null',
> +        '-c', '-xc',
> +        '@INPUT@'
> +      ]
> +    )
> +    hco_targets += hco
> +  endforeach
> +
> +  alias_target('hdr-check', hco_targets)
> +endif
> +
>   foreach key, value : {
>     'DIFF': diff.full_path(),
>     'GIT_SOURCE_DIR': meson.project_source_root(),
>
Junio C Hamano April 10, 2025, 7:06 p.m. UTC | #2
Phillip Wood <phillip.wood123@gmail.com> writes:

> Hi Karthik
>
> On 10/04/2025 12:30, Karthik Nayak wrote:
>> The Makefile supports a target called 'hdr-check', which checks if
>> individual header files can be independently compiled. Let's port this
>> functionality to meson, our new build system too. The implementation
>> resembles that of the Makefile and provides the same check.
>
> Thanks for adding this, I've left a few comments below
>
>> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
>> ---
>>   meson.build | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 107 insertions(+)
>> diff --git a/meson.build b/meson.build
>> index 790d178007..6fce1aa618 100644
>> --- a/meson.build
>> +++ b/meson.build
>> @@ -655,6 +655,12 @@ if git.found()
>>     endforeach
>>   endif
>>   +headers_generated = [
>
> To me "generated_headers" would be a more natural name and would match
> the style of "coccinelle_headers" from patch 1 as well as the
> equivalent in the Makefile.

To me too.

>> ...
>> +  'xdiff/xtypes.h',
>> +  'xdiff/xutils.h',
>> +]
>
> Having to manually maintain this list is a bit of a shame as every
> time a new file is added to compat we need to add it to meson.build
> twice. The Makefile avoids this by filtering the list of headers used
> when building git based on their path - can we do the same here?

Yup.  It cuts both ways, but generally I would prefer that.  Your
creating a new file, and saying "git add" on it, should be a sign
enough that you intend to make it a part of the project, and the
file having a name that follows the project convention (e.g., "C
header files are in certain directories and ends with .h") should be
a sign enough that you want it to be part of the build.  Forcing
people to list them explicitly is a pain.

Yes, the approach to "glob" the list of files used would not help
you catch mistakes like forgetting to "git add" new files.  You test
locally and you commit (without the new file), and you'll be
notified by whoever cloned from you about a "missing file".  But
forcing to list the files in Makefile or meson.build would not help
you catch that kind of mistake.  While it may give you one more
chance to remind yourself that you need to "git add" by ignoring a
new file until you add it to meson.build, if you add it to the file
but not to the commit, the build procedure would not complain.

So, yes, I would pretty much agree with you and prefer to see this
kind of list go, if possible.

Thanks.
Patrick Steinhardt April 11, 2025, 10:06 a.m. UTC | #3
On Thu, Apr 10, 2025 at 01:30:33PM +0200, Karthik Nayak wrote:
> The Makefile supports a target called 'hdr-check', which checks if
> individual header files can be independently compiled. Let's port this
> functionality to meson, our new build system too. The implementation

Nit: Meson is typically spelt with an upper-case 'M'.

> resembles that of the Makefile and provides the same check.
> 
> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
> ---
>  meson.build | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 107 insertions(+)
> 
> diff --git a/meson.build b/meson.build
> index 790d178007..6fce1aa618 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -655,6 +655,12 @@ if git.found()
>    endforeach
>  endif
>  
> +headers_generated = [
> +  'command-list.h',
> +  'config-list.h',
> +  'hook-list.h'
> +]
> +
>  if not get_option('breaking_changes')
>    builtin_sources += 'builtin/pack-redundant.c'
>  endif
> @@ -1995,6 +2001,107 @@ endif
>  
>  subdir('contrib')
>  
> +headers_check_exclude = headers_generated
> +headers_check_exclude += [
> +  'compat/apple-common-crypto.h',
> +  'compat/bswap.h',
> +  'compat/compiler.h',
> +  'compat/disk.h',
> +  'compat/fsmonitor/fsm-darwin-gcc.h',
> +  'compat/fsmonitor/fsm-health.h',
> +  'compat/fsmonitor/fsm-listen.h',
> +  'compat/mingw.h',
> +  'compat/msvc.h',
> +  'compat/nedmalloc/malloc.c.h',
> +  'compat/nedmalloc/nedmalloc.h',
> +  'compat/nonblock.h',
> +  'compat/obstack.h',
> +  'compat/poll/poll.h',
> +  'compat/precompose_utf8.h',
> +  'compat/regex/regex.h',
> +  'compat/regex/regex_internal.h',
> +  'compat/sha1-chunked.h',
> +  'compat/terminal.h',
> +  'compat/vcbuild/include/sys/param.h',
> +  'compat/vcbuild/include/sys/time.h',
> +  'compat/vcbuild/include/sys/utime.h',
> +  'compat/vcbuild/include/unistd.h',
> +  'compat/vcbuild/include/utime.h',
> +  'compat/win32.h',
> +  'compat/win32/alloca.h',
> +  'compat/win32/dirent.h',
> +  'compat/win32/lazyload.h',
> +  'compat/win32/path-utils.h',
> +  'compat/win32/pthread.h',
> +  'compat/win32/syslog.h',
> +  'compat/zlib-compat.h',
> +  't/unit-tests/clar/clar.h',
> +  't/unit-tests/clar/clar/fixtures.h',
> +  't/unit-tests/clar/clar/fs.h',
> +  't/unit-tests/clar/clar/print.h',
> +  't/unit-tests/clar/clar/sandbox.h',
> +  't/unit-tests/clar/clar/summary.h',
> +  't/unit-tests/clar/test/clar_test.h',
> +  'unicode-width.h',
> +  'xdiff/xdiff.h',
> +  'xdiff/xdiffi.h',
> +  'xdiff/xemit.h',
> +  'xdiff/xinclude.h',
> +  'xdiff/xmacros.h',
> +  'xdiff/xprepare.h',
> +  'xdiff/xtypes.h',
> +  'xdiff/xutils.h',
> +]

Many of these feel as if they should've been part of
`third_party_sources`.

> +if sha1_backend != 'openssl'
> +  headers_check_exclude += 'sha1/openssl.h'
> +endif
> +if sha256_backend != 'openssl'
> +  headers_check_exclude += 'sha256/openssl.h'
> +endif
> +if sha256_backend != 'nettle'
> +  headers_check_exclude += 'sha256/nettle.h'
> +endif
> +if sha256_backend != 'gcrpyt'
> +  headers_check_exclude += 'sha256/gcrypt.h'
> +endif
> +
> +if headers.length() != 0 and compiler.get_argument_syntax() == 'gcc'
> +  hco_targets = []
> +  foreach h : headers
> +    if headers_check_exclude.contains(h)
> +      continue
> +    endif
> +
> +    hcc = custom_target(
> +      input: h,
> +      output: h.underscorify() + 'cc',
> +      command: [
> +        shell,
> +        '-c',
> +        'echo \'#include "git-compat-util.h"\' > @OUTPUT@ && echo -n \'#include "' + h + '"\' >> @OUTPUT@'
> +      ]
> +    )
> +
> +    hco = custom_target(
> +      input: hcc,
> +      output: h.underscorify().replace('.h', '.hco'),

You can use `fs.replace_suffix()` instead of `.replace()`.

> +      command: [
> +        compiler.cmd_array(),
> +        libgit_c_args,
> +        '-I', meson.project_source_root(),
> +        '-I', meson.project_source_root() / 't/unit-tests',
> +        '-o', '/dev/null',
> +        '-c', '-xc',
> +        '@INPUT@'
> +      ]
> +    )
> +    hco_targets += hco
> +  endforeach
> +
> +  alias_target('hdr-check', hco_targets)
> +endif
> +
>  foreach key, value : {
>    'DIFF': diff.full_path(),
>    'GIT_SOURCE_DIR': meson.project_source_root(),

Patrick
Toon Claes April 14, 2025, 8:45 a.m. UTC | #4
Karthik Nayak <karthik.188@gmail.com> writes:

> The Makefile supports a target called 'hdr-check', which checks if
> individual header files can be independently compiled. Let's port this
> functionality to meson, our new build system too. The implementation
> resembles that of the Makefile and provides the same check.
>
> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
> ---
>  meson.build | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 107 insertions(+)
>
> diff --git a/meson.build b/meson.build
> index 790d178007..6fce1aa618 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -655,6 +655,12 @@ if git.found()
>    endforeach
>  endif
>  
> +headers_generated = [
> +  'command-list.h',
> +  'config-list.h',
> +  'hook-list.h'
> +]

Can we maybe compose this list by instead doing:

    generated_headers = []
    foreach f : builtin_sources + libgit_sources + third_party_sources
      if f.endswith(".h")
        generated_headers += f
      endif
    endforeach

(This would take `third_party_sources` into account as suggested by
Patrick[1]).

If we consider that too much magic, I would suggest:

    generated_headers = []
    builtin_sources += custom_target(
      output: 'config-list.h',
      command: [
        shell,
        meson.current_source_dir() + '/generate-configlist.sh',
        meson.current_source_dir(),
        '@OUTPUT@',
      ],
      env: script_environment,
    )
    generated_headers += 'config-list.h'

I hope this would reduce the chance to forget to add more headers to
this list (assuming people copy the code blurb from another location).

--
Toon
Karthik Nayak April 14, 2025, 1:49 p.m. UTC | #5
Phillip Wood <phillip.wood123@gmail.com> writes:

> Hi Karthik
>
> On 10/04/2025 12:30, Karthik Nayak wrote:
>> The Makefile supports a target called 'hdr-check', which checks if
>> individual header files can be independently compiled. Let's port this
>> functionality to meson, our new build system too. The implementation
>> resembles that of the Makefile and provides the same check.
>
> Thanks for adding this, I've left a few comments below
>
>> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
>> ---
>>   meson.build | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 107 insertions(+)
>>
>> diff --git a/meson.build b/meson.build
>> index 790d178007..6fce1aa618 100644
>> --- a/meson.build
>> +++ b/meson.build
>> @@ -655,6 +655,12 @@ if git.found()
>>     endforeach
>>   endif
>>
>> +headers_generated = [
>
> To me "generated_headers" would be a more natural name and would match
> the style of "coccinelle_headers" from patch 1 as well as the equivalent
> in the Makefile.
>

Yeah, makes sense, I will swap out the name.

>> +  'command-list.h',
>> +  'config-list.h',
>> +  'hook-list.h'
>> +]
>> +
>>   if not get_option('breaking_changes')
>>     builtin_sources += 'builtin/pack-redundant.c'
>>   endif
>> @@ -1995,6 +2001,107 @@ endif
>>
>>   subdir('contrib')
>>
>> +headers_check_exclude = headers_generated
>> +headers_check_exclude += [
>> +  'compat/apple-common-crypto.h',
>> +  'compat/bswap.h',
>> +  'compat/compiler.h',
>> +  'compat/disk.h',
>> +  'compat/fsmonitor/fsm-darwin-gcc.h',
>> +  'compat/fsmonitor/fsm-health.h',
>> +  'compat/fsmonitor/fsm-listen.h',
>> +  'compat/mingw.h',
>> +  'compat/msvc.h',
>> +  'compat/nedmalloc/malloc.c.h',
>> +  'compat/nedmalloc/nedmalloc.h',
>> +  'compat/nonblock.h',
>> +  'compat/obstack.h',
>> +  'compat/poll/poll.h',
>> +  'compat/precompose_utf8.h',
>> +  'compat/regex/regex.h',
>> +  'compat/regex/regex_internal.h',
>> +  'compat/sha1-chunked.h',
>> +  'compat/terminal.h',
>> +  'compat/vcbuild/include/sys/param.h',
>> +  'compat/vcbuild/include/sys/time.h',
>> +  'compat/vcbuild/include/sys/utime.h',
>> +  'compat/vcbuild/include/unistd.h',
>> +  'compat/vcbuild/include/utime.h',
>> +  'compat/win32.h',
>> +  'compat/win32/alloca.h',
>> +  'compat/win32/dirent.h',
>> +  'compat/win32/lazyload.h',
>> +  'compat/win32/path-utils.h',
>> +  'compat/win32/pthread.h',
>> +  'compat/win32/syslog.h',
>> +  'compat/zlib-compat.h',
>> +  't/unit-tests/clar/clar.h',
>> +  't/unit-tests/clar/clar/fixtures.h',
>> +  't/unit-tests/clar/clar/fs.h',
>> +  't/unit-tests/clar/clar/print.h',
>> +  't/unit-tests/clar/clar/sandbox.h',
>> +  't/unit-tests/clar/clar/summary.h',
>> +  't/unit-tests/clar/test/clar_test.h',
>> +  'unicode-width.h',
>> +  'xdiff/xdiff.h',
>> +  'xdiff/xdiffi.h',
>> +  'xdiff/xemit.h',
>> +  'xdiff/xinclude.h',
>> +  'xdiff/xmacros.h',
>> +  'xdiff/xprepare.h',
>> +  'xdiff/xtypes.h',
>> +  'xdiff/xutils.h',
>> +]
>
> Having to manually maintain this list is a bit of a shame as every time
> a new file is added to compat we need to add it to meson.build twice.
> The Makefile avoids this by filtering the list of headers used when
> building git based on their path - can we do the same here?
>

The ideology in Meson is to list all files explicitly [1] and that was
what I wanted to follow. That said I understand the reasoning, and will
implement a glob match in the next version

>> +if sha1_backend != 'openssl'
>> +  headers_check_exclude += 'sha1/openssl.h'
>> +endif
>> +if sha256_backend != 'openssl'
>> +  headers_check_exclude += 'sha256/openssl.h'
>> +endif
>> +if sha256_backend != 'nettle'
>> +  headers_check_exclude += 'sha256/nettle.h'
>> +endif
>> +if sha256_backend != 'gcrpyt'
>> +  headers_check_exclude += 'sha256/gcrypt.h'
>> +endif
>> +
>> +if headers.length() != 0 and compiler.get_argument_syntax() == 'gcc'
>> +  hco_targets = []
>> +  foreach h : headers
>> +    if headers_check_exclude.contains(h)
>> +      continue
>> +    endif
>> +
>> +    hcc = custom_target(
>> +      input: h,
>> +      output: h.underscorify() + 'cc',
>> +      command: [
>> +        shell,
>> +        '-c',
>> +        'echo \'#include "git-compat-util.h"\' > @OUTPUT@ && echo -n \'#include "' + h + '"\' >> @OUTPUT@'
>
> This line is rather long. Also do we really need "echo -n" here, the
> Makefile does not use it.
>

We can remove it, I was a bit stuck here, because of how meson converts
back-slash in 'command' [2], I eventually got this working version. But
the 'echo -n' can be changed to 'echo'.

Regarding the long line, now sure if there is a better way!

>> +      ]
>> +    )
>> +
>> +    hco = custom_target(
>> +      input: hcc,
>> +      output: h.underscorify().replace('.h', '.hco'),
>> +      command: [
>> +        compiler.cmd_array(),
>> +        libgit_c_args,
>> +        '-I', meson.project_source_root(),
>> +        '-I', meson.project_source_root() / 't/unit-tests',
>
> Do you know why we don't need to add these include paths for the
> equivalent rule in the Makefile?
>

Because the Makefile builds in-tree, so the dependencies are met. Since
meson builds are out of tree, we need to explicitly add missing
dependencies. I'll add this in the commit message.

> Thanks
>
> Phillip
>

Thanks for the review!

>> +        '-o', '/dev/null',
>> +        '-c', '-xc',
>> +        '@INPUT@'
>> +      ]
>> +    )
>> +    hco_targets += hco
>> +  endforeach
>> +
>> +  alias_target('hdr-check', hco_targets)
>> +endif
>> +
>>   foreach key, value : {
>>     'DIFF': diff.full_path(),
>>     'GIT_SOURCE_DIR': meson.project_source_root(),
>>

[1]: https://mesonbuild.com/FAQ.html#why-cant-i-specify-target-files-with-a-wildcard
[2]: https://github.com/mesonbuild/meson/issues/1564
Karthik Nayak April 14, 2025, 2:03 p.m. UTC | #6
Patrick Steinhardt <ps@pks.im> writes:

> On Thu, Apr 10, 2025 at 01:30:33PM +0200, Karthik Nayak wrote:
>> The Makefile supports a target called 'hdr-check', which checks if
>> individual header files can be independently compiled. Let's port this
>> functionality to meson, our new build system too. The implementation
>
> Nit: Meson is typically spelt with an upper-case 'M'.
>

Will modify throughout the series, thanks!

>> resembles that of the Makefile and provides the same check.
>>
>> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
>> ---
>>  meson.build | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 107 insertions(+)
>>
>> diff --git a/meson.build b/meson.build
>> index 790d178007..6fce1aa618 100644
>> --- a/meson.build
>> +++ b/meson.build
>> @@ -655,6 +655,12 @@ if git.found()
>>    endforeach
>>  endif
>>
>> +headers_generated = [
>> +  'command-list.h',
>> +  'config-list.h',
>> +  'hook-list.h'
>> +]
>> +
>>  if not get_option('breaking_changes')
>>    builtin_sources += 'builtin/pack-redundant.c'
>>  endif
>> @@ -1995,6 +2001,107 @@ endif
>>
>>  subdir('contrib')
>>
>> +headers_check_exclude = headers_generated
>> +headers_check_exclude += [
>> +  'compat/apple-common-crypto.h',
>> +  'compat/bswap.h',
>> +  'compat/compiler.h',
>> +  'compat/disk.h',
>> +  'compat/fsmonitor/fsm-darwin-gcc.h',
>> +  'compat/fsmonitor/fsm-health.h',
>> +  'compat/fsmonitor/fsm-listen.h',
>> +  'compat/mingw.h',
>> +  'compat/msvc.h',
>> +  'compat/nedmalloc/malloc.c.h',
>> +  'compat/nedmalloc/nedmalloc.h',
>> +  'compat/nonblock.h',
>> +  'compat/obstack.h',
>> +  'compat/poll/poll.h',
>> +  'compat/precompose_utf8.h',
>> +  'compat/regex/regex.h',
>> +  'compat/regex/regex_internal.h',
>> +  'compat/sha1-chunked.h',
>> +  'compat/terminal.h',
>> +  'compat/vcbuild/include/sys/param.h',
>> +  'compat/vcbuild/include/sys/time.h',
>> +  'compat/vcbuild/include/sys/utime.h',
>> +  'compat/vcbuild/include/unistd.h',
>> +  'compat/vcbuild/include/utime.h',
>> +  'compat/win32.h',
>> +  'compat/win32/alloca.h',
>> +  'compat/win32/dirent.h',
>> +  'compat/win32/lazyload.h',
>> +  'compat/win32/path-utils.h',
>> +  'compat/win32/pthread.h',
>> +  'compat/win32/syslog.h',
>> +  'compat/zlib-compat.h',
>> +  't/unit-tests/clar/clar.h',
>> +  't/unit-tests/clar/clar/fixtures.h',
>> +  't/unit-tests/clar/clar/fs.h',
>> +  't/unit-tests/clar/clar/print.h',
>> +  't/unit-tests/clar/clar/sandbox.h',
>> +  't/unit-tests/clar/clar/summary.h',
>> +  't/unit-tests/clar/test/clar_test.h',
>> +  'unicode-width.h',
>> +  'xdiff/xdiff.h',
>> +  'xdiff/xdiffi.h',
>> +  'xdiff/xemit.h',
>> +  'xdiff/xinclude.h',
>> +  'xdiff/xmacros.h',
>> +  'xdiff/xprepare.h',
>> +  'xdiff/xtypes.h',
>> +  'xdiff/xutils.h',
>> +]
>
> Many of these feel as if they should've been part of
> `third_party_sources`.
>

The condensed list is now:

exclude_from_check_headers += [
  'compat/',
  't/unit-tests/clar/',
  'unicode-width.h',
  'xdiff/',
]

I think from this:
- compat/: This captures all compat headers, I'm not sure adding all of
  compat under 'third_party_sources' makes sense though.
- t/unit-tests/clar/: can be removed, since this is already captured in
  'third_party_sources'.
- unicode-width.h: isn't a fit for 'third_party_sources'.
- xdiff/: will move to 'third_party_sources'.


>> +if sha1_backend != 'openssl'
>> +  headers_check_exclude += 'sha1/openssl.h'
>> +endif
>> +if sha256_backend != 'openssl'
>> +  headers_check_exclude += 'sha256/openssl.h'
>> +endif
>> +if sha256_backend != 'nettle'
>> +  headers_check_exclude += 'sha256/nettle.h'
>> +endif
>> +if sha256_backend != 'gcrpyt'
>> +  headers_check_exclude += 'sha256/gcrypt.h'
>> +endif
>> +
>> +if headers.length() != 0 and compiler.get_argument_syntax() == 'gcc'
>> +  hco_targets = []
>> +  foreach h : headers
>> +    if headers_check_exclude.contains(h)
>> +      continue
>> +    endif
>> +
>> +    hcc = custom_target(
>> +      input: h,
>> +      output: h.underscorify() + 'cc',
>> +      command: [
>> +        shell,
>> +        '-c',
>> +        'echo \'#include "git-compat-util.h"\' > @OUTPUT@ && echo -n \'#include "' + h + '"\' >> @OUTPUT@'
>> +      ]
>> +    )
>> +
>> +    hco = custom_target(
>> +      input: hcc,
>> +      output: h.underscorify().replace('.h', '.hco'),
>
> You can use `fs.replace_suffix()` instead of `.replace()`.
>

Nice, will do.

>> +      command: [
>> +        compiler.cmd_array(),
>> +        libgit_c_args,
>> +        '-I', meson.project_source_root(),
>> +        '-I', meson.project_source_root() / 't/unit-tests',
>> +        '-o', '/dev/null',
>> +        '-c', '-xc',
>> +        '@INPUT@'
>> +      ]
>> +    )
>> +    hco_targets += hco
>> +  endforeach
>> +
>> +  alias_target('hdr-check', hco_targets)
>> +endif
>> +
>>  foreach key, value : {
>>    'DIFF': diff.full_path(),
>>    'GIT_SOURCE_DIR': meson.project_source_root(),
>
> Patrick
Karthik Nayak April 14, 2025, 2:25 p.m. UTC | #7
Toon Claes <toon@iotcl.com> writes:

> Karthik Nayak <karthik.188@gmail.com> writes:
>
>> The Makefile supports a target called 'hdr-check', which checks if
>> individual header files can be independently compiled. Let's port this
>> functionality to meson, our new build system too. The implementation
>> resembles that of the Makefile and provides the same check.
>>
>> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
>> ---
>>  meson.build | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 107 insertions(+)
>>
>> diff --git a/meson.build b/meson.build
>> index 790d178007..6fce1aa618 100644
>> --- a/meson.build
>> +++ b/meson.build
>> @@ -655,6 +655,12 @@ if git.found()
>>    endforeach
>>  endif
>>
>> +headers_generated = [
>> +  'command-list.h',
>> +  'config-list.h',
>> +  'hook-list.h'
>> +]
>
> Can we maybe compose this list by instead doing:
>
>     generated_headers = []
>     foreach f : builtin_sources + libgit_sources + third_party_sources
>       if f.endswith(".h")
>         generated_headers += f
>       endif
>     endforeach
>
> (This would take `third_party_sources` into account as suggested by
> Patrick[1]).
>

This does make sense, but this also feels like an overkill to only get
three headers.

> If we consider that too much magic, I would suggest:
>
>     generated_headers = []
>     builtin_sources += custom_target(
>       output: 'config-list.h',
>       command: [
>         shell,
>         meson.current_source_dir() + '/generate-configlist.sh',
>         meson.current_source_dir(),
>         '@OUTPUT@',
>       ],
>       env: script_environment,
>     )
>     generated_headers += 'config-list.h'
>
> I hope this would reduce the chance to forget to add more headers to
> this list (assuming people copy the code blurb from another location).
>

This looks nice, Let me modify accordingly!

> --
> Toon
diff mbox series

Patch

diff --git a/meson.build b/meson.build
index 790d178007..6fce1aa618 100644
--- a/meson.build
+++ b/meson.build
@@ -655,6 +655,12 @@  if git.found()
   endforeach
 endif
 
+headers_generated = [
+  'command-list.h',
+  'config-list.h',
+  'hook-list.h'
+]
+
 if not get_option('breaking_changes')
   builtin_sources += 'builtin/pack-redundant.c'
 endif
@@ -1995,6 +2001,107 @@  endif
 
 subdir('contrib')
 
+headers_check_exclude = headers_generated
+headers_check_exclude += [
+  'compat/apple-common-crypto.h',
+  'compat/bswap.h',
+  'compat/compiler.h',
+  'compat/disk.h',
+  'compat/fsmonitor/fsm-darwin-gcc.h',
+  'compat/fsmonitor/fsm-health.h',
+  'compat/fsmonitor/fsm-listen.h',
+  'compat/mingw.h',
+  'compat/msvc.h',
+  'compat/nedmalloc/malloc.c.h',
+  'compat/nedmalloc/nedmalloc.h',
+  'compat/nonblock.h',
+  'compat/obstack.h',
+  'compat/poll/poll.h',
+  'compat/precompose_utf8.h',
+  'compat/regex/regex.h',
+  'compat/regex/regex_internal.h',
+  'compat/sha1-chunked.h',
+  'compat/terminal.h',
+  'compat/vcbuild/include/sys/param.h',
+  'compat/vcbuild/include/sys/time.h',
+  'compat/vcbuild/include/sys/utime.h',
+  'compat/vcbuild/include/unistd.h',
+  'compat/vcbuild/include/utime.h',
+  'compat/win32.h',
+  'compat/win32/alloca.h',
+  'compat/win32/dirent.h',
+  'compat/win32/lazyload.h',
+  'compat/win32/path-utils.h',
+  'compat/win32/pthread.h',
+  'compat/win32/syslog.h',
+  'compat/zlib-compat.h',
+  't/unit-tests/clar/clar.h',
+  't/unit-tests/clar/clar/fixtures.h',
+  't/unit-tests/clar/clar/fs.h',
+  't/unit-tests/clar/clar/print.h',
+  't/unit-tests/clar/clar/sandbox.h',
+  't/unit-tests/clar/clar/summary.h',
+  't/unit-tests/clar/test/clar_test.h',
+  'unicode-width.h',
+  'xdiff/xdiff.h',
+  'xdiff/xdiffi.h',
+  'xdiff/xemit.h',
+  'xdiff/xinclude.h',
+  'xdiff/xmacros.h',
+  'xdiff/xprepare.h',
+  'xdiff/xtypes.h',
+  'xdiff/xutils.h',
+]
+
+if sha1_backend != 'openssl'
+  headers_check_exclude += 'sha1/openssl.h'
+endif
+if sha256_backend != 'openssl'
+  headers_check_exclude += 'sha256/openssl.h'
+endif
+if sha256_backend != 'nettle'
+  headers_check_exclude += 'sha256/nettle.h'
+endif
+if sha256_backend != 'gcrpyt'
+  headers_check_exclude += 'sha256/gcrypt.h'
+endif
+
+if headers.length() != 0 and compiler.get_argument_syntax() == 'gcc'
+  hco_targets = []
+  foreach h : headers
+    if headers_check_exclude.contains(h)
+      continue
+    endif
+
+    hcc = custom_target(
+      input: h,
+      output: h.underscorify() + 'cc',
+      command: [
+        shell,
+        '-c',
+        'echo \'#include "git-compat-util.h"\' > @OUTPUT@ && echo -n \'#include "' + h + '"\' >> @OUTPUT@'
+      ]
+    )
+
+    hco = custom_target(
+      input: hcc,
+      output: h.underscorify().replace('.h', '.hco'),
+      command: [
+        compiler.cmd_array(),
+        libgit_c_args,
+        '-I', meson.project_source_root(),
+        '-I', meson.project_source_root() / 't/unit-tests',
+        '-o', '/dev/null',
+        '-c', '-xc',
+        '@INPUT@'
+      ]
+    )
+    hco_targets += hco
+  endforeach
+
+  alias_target('hdr-check', hco_targets)
+endif
+
 foreach key, value : {
   'DIFF': diff.full_path(),
   'GIT_SOURCE_DIR': meson.project_source_root(),