[v2,16/19] app/chkincs: add chkincs app to verify headers

Message ID 20210115111052.16437-17-bruce.richardson@intel.com (mailing list archive)
State Superseded, archived
Delegated to: David Marchand
Headers
Series ensure headers have correct includes |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Bruce Richardson Jan. 15, 2021, 11:10 a.m. UTC
  To verify that all DPDK headers are ok for inclusion directly in a C
file, and are not missing any other pre-requisite headers, we can
auto-generate for each header an empty C file that includes that header.
Compiling these files will throw errors if any header has unmet
dependencies.

The list of headers to check is based of the "headers" value returned from
each library's meson.build file. However, since not all headers are for
direct inclusion, add a build variable "headers_no_chkincs" to list those
headers and skip checking them.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---

v2:
* add maintainers entry
* distribute exception list among meson.build files.

 MAINTAINERS                              |  4 ++++
 app/chkincs/gen_c_file_for_header.py     | 12 ++++++++++
 app/chkincs/main.c                       |  4 ++++
 app/chkincs/meson.build                  | 28 ++++++++++++++++++++++++
 app/meson.build                          |  1 +
 doc/guides/contributing/coding_style.rst | 12 ++++++++++
 lib/librte_eal/include/meson.build       |  2 +-
 lib/librte_ethdev/meson.build            |  4 ++--
 lib/librte_hash/meson.build              |  4 ++--
 lib/librte_ipsec/meson.build             |  3 ++-
 lib/librte_lpm/meson.build               |  2 +-
 lib/librte_regexdev/meson.build          |  2 +-
 lib/librte_ring/meson.build              |  4 +++-
 lib/librte_stack/meson.build             |  4 +++-
 lib/librte_table/meson.build             |  7 +++---
 lib/meson.build                          |  3 +++
 meson.build                              |  1 +
 meson_options.txt                        |  2 ++
 18 files changed, 85 insertions(+), 14 deletions(-)
 create mode 100755 app/chkincs/gen_c_file_for_header.py
 create mode 100644 app/chkincs/main.c
 create mode 100644 app/chkincs/meson.build

--
2.27.0
  

Comments

Ferruh Yigit Jan. 15, 2021, 11:51 a.m. UTC | #1
On 1/15/2021 11:10 AM, Bruce Richardson wrote:
> To verify that all DPDK headers are ok for inclusion directly in a C
> file, and are not missing any other pre-requisite headers, we can
> auto-generate for each header an empty C file that includes that header.
> Compiling these files will throw errors if any header has unmet
> dependencies.
> 
> The list of headers to check is based of the "headers" value returned from
> each library's meson.build file. However, since not all headers are for
> direct inclusion, add a build variable "headers_no_chkincs" to list those
> headers and skip checking them.
> 
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> ---
> 
> v2:
> * add maintainers entry
> * distribute exception list among meson.build files.
> 
>   MAINTAINERS                              |  4 ++++
>   app/chkincs/gen_c_file_for_header.py     | 12 ++++++++++
>   app/chkincs/main.c                       |  4 ++++
>   app/chkincs/meson.build                  | 28 ++++++++++++++++++++++++

+1 to have this kind of tool to check, but it is not an application like others 
in the 'app' folder, what do you think placing it under 'devtools' or 'buildtools'?
  
Bruce Richardson Jan. 15, 2021, 11:59 a.m. UTC | #2
On Fri, Jan 15, 2021 at 11:51:49AM +0000, Ferruh Yigit wrote:
> On 1/15/2021 11:10 AM, Bruce Richardson wrote:
> > To verify that all DPDK headers are ok for inclusion directly in a C
> > file, and are not missing any other pre-requisite headers, we can
> > auto-generate for each header an empty C file that includes that header.
> > Compiling these files will throw errors if any header has unmet
> > dependencies.
> > 
> > The list of headers to check is based of the "headers" value returned from
> > each library's meson.build file. However, since not all headers are for
> > direct inclusion, add a build variable "headers_no_chkincs" to list those
> > headers and skip checking them.
> > 
> > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > ---
> > 
> > v2:
> > * add maintainers entry
> > * distribute exception list among meson.build files.
> > 
> >   MAINTAINERS                              |  4 ++++
> >   app/chkincs/gen_c_file_for_header.py     | 12 ++++++++++
> >   app/chkincs/main.c                       |  4 ++++
> >   app/chkincs/meson.build                  | 28 ++++++++++++++++++++++++
> 
> +1 to have this kind of tool to check, but it is not an application like
> others in the 'app' folder, what do you think placing it under 'devtools' or
> 'buildtools'?

Couple of reasons why it's placed in app.

1. We previously had a "chkincs" app in DPDK which was kept in the app
folder
2. It allows us to reuse the build infrastructure for building apps, rather
than reduplicating it.
3. We don't have any compilable code currently in the devtools folder, and
even in buildtools the pmdinfogen app is going to go away.

That being said, none of those reasons are major issues that can't be
worked around if the consensus is to move it.

/Bruce
  
Thomas Monjalon Jan. 15, 2021, 2:09 p.m. UTC | #3
15/01/2021 12:59, Bruce Richardson:
> On Fri, Jan 15, 2021 at 11:51:49AM +0000, Ferruh Yigit wrote:
> > On 1/15/2021 11:10 AM, Bruce Richardson wrote:
> > > To verify that all DPDK headers are ok for inclusion directly in a C
> > > file, and are not missing any other pre-requisite headers, we can
> > > auto-generate for each header an empty C file that includes that header.
> > > Compiling these files will throw errors if any header has unmet
> > > dependencies.
> > > 
> > > The list of headers to check is based of the "headers" value returned from
> > > each library's meson.build file. However, since not all headers are for
> > > direct inclusion, add a build variable "headers_no_chkincs" to list those
> > > headers and skip checking them.
> > > 
> > > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > > ---
> > > 
> > > v2:
> > > * add maintainers entry
> > > * distribute exception list among meson.build files.
> > > 
> > >   MAINTAINERS                              |  4 ++++
> > >   app/chkincs/gen_c_file_for_header.py     | 12 ++++++++++
> > >   app/chkincs/main.c                       |  4 ++++
> > >   app/chkincs/meson.build                  | 28 ++++++++++++++++++++++++
> > 
> > +1 to have this kind of tool to check, but it is not an application like
> > others in the 'app' folder, what do you think placing it under 'devtools' or
> > 'buildtools'?
> 
> Couple of reasons why it's placed in app.
> 
> 1. We previously had a "chkincs" app in DPDK which was kept in the app
> folder
> 2. It allows us to reuse the build infrastructure for building apps, rather
> than reduplicating it.
> 3. We don't have any compilable code currently in the devtools folder, and
> even in buildtools the pmdinfogen app is going to go away.
> 
> That being said, none of those reasons are major issues that can't be
> worked around if the consensus is to move it.

It could be easily in devtools if it was a script.
By the way, we already have devtools/check-includes.sh
If your solution is better, please remove this script.
  
Bruce Richardson Jan. 15, 2021, 2:55 p.m. UTC | #4
On Fri, Jan 15, 2021 at 03:09:25PM +0100, Thomas Monjalon wrote:
> 15/01/2021 12:59, Bruce Richardson:
> > On Fri, Jan 15, 2021 at 11:51:49AM +0000, Ferruh Yigit wrote:
> > > On 1/15/2021 11:10 AM, Bruce Richardson wrote:
> > > > To verify that all DPDK headers are ok for inclusion directly in a C
> > > > file, and are not missing any other pre-requisite headers, we can
> > > > auto-generate for each header an empty C file that includes that header.
> > > > Compiling these files will throw errors if any header has unmet
> > > > dependencies.
> > > > 
> > > > The list of headers to check is based of the "headers" value returned from
> > > > each library's meson.build file. However, since not all headers are for
> > > > direct inclusion, add a build variable "headers_no_chkincs" to list those
> > > > headers and skip checking them.
> > > > 
> > > > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > > > ---
> > > > 
> > > > v2:
> > > > * add maintainers entry
> > > > * distribute exception list among meson.build files.
> > > > 
> > > >   MAINTAINERS                              |  4 ++++
> > > >   app/chkincs/gen_c_file_for_header.py     | 12 ++++++++++
> > > >   app/chkincs/main.c                       |  4 ++++
> > > >   app/chkincs/meson.build                  | 28 ++++++++++++++++++++++++
> > > 
> > > +1 to have this kind of tool to check, but it is not an application like
> > > others in the 'app' folder, what do you think placing it under 'devtools' or
> > > 'buildtools'?
> > 
> > Couple of reasons why it's placed in app.
> > 
> > 1. We previously had a "chkincs" app in DPDK which was kept in the app
> > folder
> > 2. It allows us to reuse the build infrastructure for building apps, rather
> > than reduplicating it.
> > 3. We don't have any compilable code currently in the devtools folder, and
> > even in buildtools the pmdinfogen app is going to go away.
> > 
> > That being said, none of those reasons are major issues that can't be
> > worked around if the consensus is to move it.
> 
> It could be easily in devtools if it was a script.
> By the way, we already have devtools/check-includes.sh
> If your solution is better, please remove this script.
> 
I only discovered the script existed when doing the v2 of this patchset,
since it showed up in some grep calls I did for exception cases. I'm not
sure that either approach is necessarily better, it's just right now that
the script is unused (and also unknown) which is why I did this cleanup
work.

Here is how I see the current comparison between two approaches:
* Script as advantage in that it performs C++ checks as well as C
* Script also allows passing arbitrary additional C flags into checks for
  higher levels of compliance, but I'm not sure this is something I like as
  I'd rather have standardisation here across all headers than have some
  headers more pedantic-friendly than others.
* Main downside of the script is that is works off directories rather than
  a list of files, which means it requires maintenance of the exception
  list in the script, rather than in the build definition files where we call
  out the headers to be installed

I'm honestly fine either way on this (as with directory where
implementation lives) - main thing is to have the checking done, rather
than ignored.

/Bruce
  
Bruce Richardson Jan. 15, 2021, 2:59 p.m. UTC | #5
On Fri, Jan 15, 2021 at 02:55:41PM +0000, Bruce Richardson wrote:
> On Fri, Jan 15, 2021 at 03:09:25PM +0100, Thomas Monjalon wrote:
> > 15/01/2021 12:59, Bruce Richardson:
> > > On Fri, Jan 15, 2021 at 11:51:49AM +0000, Ferruh Yigit wrote:
> > > > On 1/15/2021 11:10 AM, Bruce Richardson wrote:
> > > > > To verify that all DPDK headers are ok for inclusion directly in a C
> > > > > file, and are not missing any other pre-requisite headers, we can
> > > > > auto-generate for each header an empty C file that includes that header.
> > > > > Compiling these files will throw errors if any header has unmet
> > > > > dependencies.
> > > > > 
> > > > > The list of headers to check is based of the "headers" value returned from
> > > > > each library's meson.build file. However, since not all headers are for
> > > > > direct inclusion, add a build variable "headers_no_chkincs" to list those
> > > > > headers and skip checking them.
> > > > > 
> > > > > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > > > > ---
> > > > > 
> > > > > v2:
> > > > > * add maintainers entry
> > > > > * distribute exception list among meson.build files.
> > > > > 
> > > > >   MAINTAINERS                              |  4 ++++
> > > > >   app/chkincs/gen_c_file_for_header.py     | 12 ++++++++++
> > > > >   app/chkincs/main.c                       |  4 ++++
> > > > >   app/chkincs/meson.build                  | 28 ++++++++++++++++++++++++
> > > > 
> > > > +1 to have this kind of tool to check, but it is not an application like
> > > > others in the 'app' folder, what do you think placing it under 'devtools' or
> > > > 'buildtools'?
> > > 
> > > Couple of reasons why it's placed in app.
> > > 
> > > 1. We previously had a "chkincs" app in DPDK which was kept in the app
> > > folder
> > > 2. It allows us to reuse the build infrastructure for building apps, rather
> > > than reduplicating it.
> > > 3. We don't have any compilable code currently in the devtools folder, and
> > > even in buildtools the pmdinfogen app is going to go away.
> > > 
> > > That being said, none of those reasons are major issues that can't be
> > > worked around if the consensus is to move it.
> > 
> > It could be easily in devtools if it was a script.
> > By the way, we already have devtools/check-includes.sh
> > If your solution is better, please remove this script.
> > 
> I only discovered the script existed when doing the v2 of this patchset,
> since it showed up in some grep calls I did for exception cases. I'm not
> sure that either approach is necessarily better, it's just right now that
> the script is unused (and also unknown) which is why I did this cleanup
> work.
> 
> Here is how I see the current comparison between two approaches:
> * Script as advantage in that it performs C++ checks as well as C
> * Script also allows passing arbitrary additional C flags into checks for
>   higher levels of compliance, but I'm not sure this is something I like as
>   I'd rather have standardisation here across all headers than have some
>   headers more pedantic-friendly than others.
> * Main downside of the script is that is works off directories rather than
>   a list of files, which means it requires maintenance of the exception
>   list in the script, rather than in the build definition files where we call
>   out the headers to be installed
> 
> I'm honestly fine either way on this (as with directory where
> implementation lives) - main thing is to have the checking done, rather
> than ignored.
> 
And I (obviously) forgot to mention that the existing script is not currently
integrated into existing build or build-test scripts. I haven't looked into
how complex this would be, but it would require investigation time.
  
Bruce Richardson Jan. 20, 2021, 2:34 p.m. UTC | #6
On Fri, Jan 15, 2021 at 02:59:08PM +0000, Bruce Richardson wrote:
> On Fri, Jan 15, 2021 at 02:55:41PM +0000, Bruce Richardson wrote:
> > On Fri, Jan 15, 2021 at 03:09:25PM +0100, Thomas Monjalon wrote:
> > > 15/01/2021 12:59, Bruce Richardson:
> > > > On Fri, Jan 15, 2021 at 11:51:49AM +0000, Ferruh Yigit wrote:
> > > > > On 1/15/2021 11:10 AM, Bruce Richardson wrote:
> > > > > > To verify that all DPDK headers are ok for inclusion directly in a C
> > > > > > file, and are not missing any other pre-requisite headers, we can
> > > > > > auto-generate for each header an empty C file that includes that header.
> > > > > > Compiling these files will throw errors if any header has unmet
> > > > > > dependencies.
> > > > > > 
> > > > > > The list of headers to check is based of the "headers" value returned from
> > > > > > each library's meson.build file. However, since not all headers are for
> > > > > > direct inclusion, add a build variable "headers_no_chkincs" to list those
> > > > > > headers and skip checking them.
> > > > > > 
> > > > > > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > > > > > ---
> > > > > > 
> > > > > > v2:
> > > > > > * add maintainers entry
> > > > > > * distribute exception list among meson.build files.
> > > > > > 
> > > > > >   MAINTAINERS                              |  4 ++++
> > > > > >   app/chkincs/gen_c_file_for_header.py     | 12 ++++++++++
> > > > > >   app/chkincs/main.c                       |  4 ++++
> > > > > >   app/chkincs/meson.build                  | 28 ++++++++++++++++++++++++
> > > > > 
> > > > > +1 to have this kind of tool to check, but it is not an application like
> > > > > others in the 'app' folder, what do you think placing it under 'devtools' or
> > > > > 'buildtools'?
> > > > 
> > > > Couple of reasons why it's placed in app.
> > > > 
> > > > 1. We previously had a "chkincs" app in DPDK which was kept in the app
> > > > folder
> > > > 2. It allows us to reuse the build infrastructure for building apps, rather
> > > > than reduplicating it.
> > > > 3. We don't have any compilable code currently in the devtools folder, and
> > > > even in buildtools the pmdinfogen app is going to go away.
> > > > 
> > > > That being said, none of those reasons are major issues that can't be
> > > > worked around if the consensus is to move it.
> > > 
> > > It could be easily in devtools if it was a script.
> > > By the way, we already have devtools/check-includes.sh
> > > If your solution is better, please remove this script.
> > > 
> > I only discovered the script existed when doing the v2 of this patchset,
> > since it showed up in some grep calls I did for exception cases. I'm not
> > sure that either approach is necessarily better, it's just right now that
> > the script is unused (and also unknown) which is why I did this cleanup
> > work.
> > 
> > Here is how I see the current comparison between two approaches:
> > * Script as advantage in that it performs C++ checks as well as C
> > * Script also allows passing arbitrary additional C flags into checks for
> >   higher levels of compliance, but I'm not sure this is something I like as
> >   I'd rather have standardisation here across all headers than have some
> >   headers more pedantic-friendly than others.
> > * Main downside of the script is that is works off directories rather than
> >   a list of files, which means it requires maintenance of the exception
> >   list in the script, rather than in the build definition files where we call
> >   out the headers to be installed
> > 
> > I'm honestly fine either way on this (as with directory where
> > implementation lives) - main thing is to have the checking done, rather
> > than ignored.
> > 
> And I (obviously) forgot to mention that the existing script is not currently
> integrated into existing build or build-test scripts. I haven't looked into
> how complex this would be, but it would require investigation time.

I do plan to look into re-using the script and other options around this
area - hopefully in RC2 timeframe. However, to make the patchset rework a
little easier, perhaps the small header fixes could be picked up for ahead
of any rework?

/Bruce
  
David Marchand Jan. 20, 2021, 3:05 p.m. UTC | #7
On Wed, Jan 20, 2021 at 3:34 PM Bruce Richardson
<bruce.richardson@intel.com> wrote:
> On Fri, Jan 15, 2021 at 02:59:08PM +0000, Bruce Richardson wrote:
> > On Fri, Jan 15, 2021 at 02:55:41PM +0000, Bruce Richardson wrote:
> > > On Fri, Jan 15, 2021 at 03:09:25PM +0100, Thomas Monjalon wrote:
> > > I'm honestly fine either way on this (as with directory where
> > > implementation lives) - main thing is to have the checking done, rather
> > > than ignored.
> > >
> > And I (obviously) forgot to mention that the existing script is not currently
> > integrated into existing build or build-test scripts. I haven't looked into
> > how complex this would be, but it would require investigation time.
>
> I do plan to look into re-using the script and other options around this
> area - hopefully in RC2 timeframe. However, to make the patchset rework a
> little easier, perhaps the small header fixes could be picked up for ahead
> of any rework?

I'll merge those fixes hopefully tomorrow.
  

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index 76ed473e44..49bb2aab2c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1561,6 +1561,10 @@  F: app/test/test_resource.c
 F: app/test/virtual_pmd.c
 F: app/test/virtual_pmd.h

+Header build sanity checking
+M: Bruce Richardson <bruce.richardson@intel.com>
+F: app/chkincs/
+
 Sample packet helper functions for unit test
 M: Reshma Pattan <reshma.pattan@intel.com>
 F: app/test/sample_packet_forward.c
diff --git a/app/chkincs/gen_c_file_for_header.py b/app/chkincs/gen_c_file_for_header.py
new file mode 100755
index 0000000000..124cf96917
--- /dev/null
+++ b/app/chkincs/gen_c_file_for_header.py
@@ -0,0 +1,12 @@ 
+#! /usr/bin/env python3
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2020-2021 Intel Corporation
+
+from sys import argv
+from os.path import abspath
+
+(h_file, c_file) = argv[1:]
+
+contents = '#include "' + abspath(h_file) + '"'
+with open(c_file, 'w') as cf:
+    cf.write(contents)
diff --git a/app/chkincs/main.c b/app/chkincs/main.c
new file mode 100644
index 0000000000..ecdf641954
--- /dev/null
+++ b/app/chkincs/main.c
@@ -0,0 +1,4 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020-2021 Intel Corporation
+ */
+int main(void) { return 0; }
diff --git a/app/chkincs/meson.build b/app/chkincs/meson.build
new file mode 100644
index 0000000000..7fea11c506
--- /dev/null
+++ b/app/chkincs/meson.build
@@ -0,0 +1,28 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2020-2021 Intel Corporation
+
+if not get_option('test_includes')
+	build = false
+	subdir_done()
+endif
+
+if is_windows
+	# for windows, the shebang line in the script won't work.
+	error('option "test_includes" is not supported on windows')
+endif
+
+gen_c_file_for_header = find_program('gen_c_file_for_header.py')
+gen_c_files = generator(gen_c_file_for_header,
+	output: '@BASENAME@.c',
+	arguments: ['@INPUT@', '@OUTPUT@'])
+
+cflags += '-Wno-unused-function' # needed if we include generic headers
+
+# some ethdev headers depend on bus headers
+includes += include_directories('../../drivers/bus/pci',
+	'../../drivers/bus/vdev')
+
+sources += files('main.c')
+sources += gen_c_files.process(dpdk_chkinc_headers)
+
+deps = enabled_libs
diff --git a/app/meson.build b/app/meson.build
index 87fc195dbf..b8ee6d2e97 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -6,6 +6,7 @@  if is_windows
 endif

 apps = [
+	'chkincs',
 	'pdump',
 	'proc-info',
 	'test-acl',
diff --git a/doc/guides/contributing/coding_style.rst b/doc/guides/contributing/coding_style.rst
index bb3f3efcbc..041a3998ff 100644
--- a/doc/guides/contributing/coding_style.rst
+++ b/doc/guides/contributing/coding_style.rst
@@ -891,6 +891,18 @@  headers
 	installed to $PREFIX/include when ``ninja install`` is run. As with
 	source files, these should be specified using the meson ``files()``
 	function.
+	When ``test_headers`` build option is set to ``true``, each header file
+	has additional checks performed on it, for example to ensure that it is
+	not missing any include statements for dependent headers. These build
+	checks are done by the build of the ``dpdk-chkincs`` application, and
+	for header files which are public, but only included indirectly in
+	applications, these checks can be skipped by using the ``headers_no_chkincs``
+	variable rather than ``headers``.
+
+headers_no_chkincs
+	**Default Value = []**.
+	As with ``headers`` option above, except that the files are not checked
+	as part of the build of the ``dpdk-chkincs`` binary.

 includes:
 	**Default Value = []**.
diff --git a/lib/librte_eal/include/meson.build b/lib/librte_eal/include/meson.build
index 0dea342e1d..449740e510 100644
--- a/lib/librte_eal/include/meson.build
+++ b/lib/librte_eal/include/meson.build
@@ -16,7 +16,6 @@  headers += files(
 	'rte_dev.h',
 	'rte_devargs.h',
 	'rte_eal.h',
-	'rte_eal_interrupts.h',
 	'rte_eal_memconfig.h',
 	'rte_eal_trace.h',
 	'rte_errno.h',
@@ -49,6 +48,7 @@  headers += files(
 	'rte_version.h',
 	'rte_vfio.h',
 )
+headers_no_chkincs += files('rte_eal_interrupts.h')

 # special case install the generic headers, since they go in a subdir
 generic_headers = files(
diff --git a/lib/librte_ethdev/meson.build b/lib/librte_ethdev/meson.build
index e4b610246f..ab84869ea8 100644
--- a/lib/librte_ethdev/meson.build
+++ b/lib/librte_ethdev/meson.build
@@ -12,12 +12,10 @@  sources = files('ethdev_private.c',

 headers = files('rte_ethdev.h',
 	'rte_ethdev_driver.h',
-	'rte_ethdev_core.h',
 	'rte_ethdev_pci.h',
 	'rte_ethdev_trace.h',
 	'rte_ethdev_trace_fp.h',
 	'rte_ethdev_vdev.h',
-	'rte_eth_ctrl.h',
 	'rte_dev_info.h',
 	'rte_flow.h',
 	'rte_flow_driver.h',
@@ -25,5 +23,7 @@  headers = files('rte_ethdev.h',
 	'rte_mtr_driver.h',
 	'rte_tm.h',
 	'rte_tm_driver.h')
+headers_no_chkincs += files('rte_eth_ctrl.h',
+	'rte_ethdev_core.h')

 deps += ['net', 'kvargs', 'meter', 'telemetry']
diff --git a/lib/librte_hash/meson.build b/lib/librte_hash/meson.build
index 0977a63fd2..b3ebc8b078 100644
--- a/lib/librte_hash/meson.build
+++ b/lib/librte_hash/meson.build
@@ -1,12 +1,12 @@ 
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation

-headers = files('rte_crc_arm64.h',
-	'rte_fbk_hash.h',
+headers = files('rte_fbk_hash.h',
 	'rte_hash_crc.h',
 	'rte_hash.h',
 	'rte_jhash.h',
 	'rte_thash.h')
+headers_no_chkincs += files('rte_crc_arm64.h')

 sources = files('rte_cuckoo_hash.c', 'rte_fbk_hash.c')
 deps += ['ring']
diff --git a/lib/librte_ipsec/meson.build b/lib/librte_ipsec/meson.build
index fc69970ec5..e24e6ed22b 100644
--- a/lib/librte_ipsec/meson.build
+++ b/lib/librte_ipsec/meson.build
@@ -3,6 +3,7 @@ 

 sources = files('esp_inb.c', 'esp_outb.c', 'sa.c', 'ses.c', 'ipsec_sad.c')

-headers = files('rte_ipsec.h', 'rte_ipsec_group.h', 'rte_ipsec_sa.h', 'rte_ipsec_sad.h')
+headers = files('rte_ipsec.h', 'rte_ipsec_sa.h', 'rte_ipsec_sad.h')
+headers_no_chkincs += files('rte_ipsec_group.h')

 deps += ['mbuf', 'net', 'cryptodev', 'security', 'hash']
diff --git a/lib/librte_lpm/meson.build b/lib/librte_lpm/meson.build
index f93c866409..3d3d515a4d 100644
--- a/lib/librte_lpm/meson.build
+++ b/lib/librte_lpm/meson.build
@@ -5,6 +5,6 @@  sources = files('rte_lpm.c', 'rte_lpm6.c')
 headers = files('rte_lpm.h', 'rte_lpm6.h')
 # since header files have different names, we can install all vector headers
 # without worrying about which architecture we actually need
-headers += files('rte_lpm_altivec.h', 'rte_lpm_neon.h', 'rte_lpm_sse.h', 'rte_lpm_sve.h')
+headers_no_chkincs += files('rte_lpm_altivec.h', 'rte_lpm_neon.h', 'rte_lpm_sse.h', 'rte_lpm_sve.h')
 deps += ['hash']
 deps += ['rcu']
diff --git a/lib/librte_regexdev/meson.build b/lib/librte_regexdev/meson.build
index c417b9caf0..1ab21bd4d8 100644
--- a/lib/librte_regexdev/meson.build
+++ b/lib/librte_regexdev/meson.build
@@ -3,6 +3,6 @@ 

 sources = files('rte_regexdev.c')
 headers = files('rte_regexdev.h',
-	'rte_regexdev_core.h',
 	'rte_regexdev_driver.h')
+headers_no_chkincs += files('rte_regexdev_core.h')
 deps += ['mbuf']
diff --git a/lib/librte_ring/meson.build b/lib/librte_ring/meson.build
index 36fdcb6a57..1a95dae9e5 100644
--- a/lib/librte_ring/meson.build
+++ b/lib/librte_ring/meson.build
@@ -2,7 +2,9 @@ 
 # Copyright(c) 2017 Intel Corporation

 sources = files('rte_ring.c')
-headers = files('rte_ring.h',
+headers = files('rte_ring.h')
+# most sub-headers are not for direct inclusion
+headers_no_chkincs += files (
 		'rte_ring_core.h',
 		'rte_ring_elem.h',
 		'rte_ring_c11_mem.h',
diff --git a/lib/librte_stack/meson.build b/lib/librte_stack/meson.build
index 8f82a40ec2..5d9b3601b3 100644
--- a/lib/librte_stack/meson.build
+++ b/lib/librte_stack/meson.build
@@ -2,7 +2,9 @@ 
 # Copyright(c) 2019 Intel Corporation

 sources = files('rte_stack.c', 'rte_stack_std.c', 'rte_stack_lf.c')
-headers = files('rte_stack.h',
+headers = files('rte_stack.h')
+# subheaders, not for direct inclusion by apps
+headers_no_chkincs += files(
 		'rte_stack_std.h',
 		'rte_stack_lf.h',
 		'rte_stack_lf_generic.h',
diff --git a/lib/librte_table/meson.build b/lib/librte_table/meson.build
index d69678386e..a8b1c9a254 100644
--- a/lib/librte_table/meson.build
+++ b/lib/librte_table/meson.build
@@ -20,7 +20,6 @@  headers = files('rte_table.h',
 		'rte_table_hash.h',
 		'rte_table_hash_cuckoo.h',
 		'rte_table_hash_func.h',
-		'rte_table_hash_func_arm64.h',
 		'rte_lru.h',
 		'rte_table_array.h',
 		'rte_table_stub.h',
@@ -28,6 +27,6 @@  headers = files('rte_table.h',
 		'rte_swx_table_em.h',)
 deps += ['mbuf', 'port', 'lpm', 'hash', 'acl']

-if arch_subdir == 'x86'
-	headers += files('rte_lru_x86.h')
-endif
+headers_no_chkincs += files('rte_lru_x86.h',
+		'rte_lru_arm64.h',
+		'rte_table_hash_func_arm64.h')
diff --git a/lib/meson.build b/lib/meson.build
index ed00f89146..404809bd44 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -65,6 +65,7 @@  foreach l:libraries
 	use_function_versioning = false
 	sources = []
 	headers = []
+	headers_no_chkincs = [] # public headers not directly included by apps
 	includes = []
 	cflags = default_cflags
 	objs = [] # other object files to link against, used e.g. for
@@ -103,6 +104,8 @@  foreach l:libraries
 		dpdk_conf.set('RTE_LIBRTE_' + name.to_upper(), 1) #old macro
 		dpdk_conf.set('RTE_LIB_' + name.to_upper(), 1) # new macro
 		install_headers(headers)
+		install_headers(headers_no_chkincs)
+		dpdk_chkinc_headers += headers

 		libname = 'rte_' + name
 		includes += include_directories(dir_name)
diff --git a/meson.build b/meson.build
index 45d974cd2c..7c9a8fce5f 100644
--- a/meson.build
+++ b/meson.build
@@ -16,6 +16,7 @@  cc = meson.get_compiler('c')
 dpdk_conf = configuration_data()
 dpdk_libraries = []
 dpdk_static_libraries = []
+dpdk_chkinc_headers = []
 dpdk_driver_classes = []
 dpdk_drivers = []
 dpdk_extra_ldflags = []
diff --git a/meson_options.txt b/meson_options.txt
index 4604328224..37cd6e99ea 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -30,5 +30,7 @@  option('enable_trace_fp', type: 'boolean', value: false,
 	description: 'enable fast path trace points.')
 option('tests', type: 'boolean', value: true,
 	description: 'build unit tests')
+option('test_includes', type: 'boolean', value: false,
+	description: 'build "chkincs" to verify each header file can compile alone')
 option('use_hpet', type: 'boolean', value: false,
 	description: 'use HPET timer in EAL')