[PATCH] Add missing includes to headers
Support build systems like bazel that check that headers are
self-contained.
Signed-off-by: Peter Foley
On Thu, 19 Feb 2026 13:44:54 -0500
Peter Foley
Support build systems like bazel that check that headers are self-contained.
Signed-off-by: Peter Foley
Thanks for the patch, Peter! It looks obviously correct to me, but I still have a question: do you happen to have a Bazel BUILD file somewhere (we could also add it to passt's contrib/ if it's not in any other repository) to check future changes against it? Otherwise we risk breaking Bazel builds again soon. I'll review and apply within a couple of days regardless of that. -- Stefano
On Thu, Feb 19, 2026 at 01:44:54PM -0500, Peter Foley wrote:
Support build systems like bazel that check that headers are self-contained.
Signed-off-by: Peter Foley
There are kind of two schools of thoughts on headers. One is that every header should #include anything it relies on. The other is that headers should #include nothing, and .c files should includde everything they need in the right order. The advantages of the second approach are that it makes it easier to keep #includes in .c files minimal, and makes circular dependencies more obvious and easier to dientanble. We've kinda sorta been using approach two in passt, but not entirely, and honestly, it's not really working. So I'm happy to convert to the former approach. However, if we're adding #includes in the headers so they're self contained, then we should be able to also *remove* a bunch of #includes from .c files (and other .h files) which were previously only there to satisfy the indirect dependencies.
--- flow.h | 6 ++++++ flow_table.h | 1 + icmp_flow.h | 2 ++ inany.h | 5 +++++ ip.h | 2 ++ linux_dep.h | 3 +++ pif.h | 4 ++++ seccomp.sh | 5 +++++ siphash.h | 3 +++ tap.h | 5 +++++ tcp_conn.h | 4 ++++ tcp_internal.h | 5 +++++ udp_internal.h | 3 +++ util.c | 1 + 14 files changed, 49 insertions(+)
diff --git a/flow.h b/flow.h index d636358..897c9ea 100644 --- a/flow.h +++ b/flow.h @@ -7,6 +7,12 @@ #ifndef FLOW_H #define FLOW_H
+#include
+#include + +#include "inany.h" +#include "util.h" + #define FLOW_TIMER_INTERVAL 1000 /* ms */ /** diff --git a/flow_table.h b/flow_table.h index 73de13b..8fb7b5c 100644 --- a/flow_table.h +++ b/flow_table.h @@ -7,6 +7,7 @@ #ifndef FLOW_TABLE_H #define FLOW_TABLE_H
+#include "pif.h" #include "tcp_conn.h" #include "icmp_flow.h" #include "udp_flow.h" diff --git a/icmp_flow.h b/icmp_flow.h index fb93801..3af98be 100644 --- a/icmp_flow.h +++ b/icmp_flow.h @@ -7,6 +7,8 @@ #ifndef ICMP_FLOW_H #define ICMP_FLOW_H
+#include "flow.h" + /** * struct icmp_ping_flow - Descriptor for a flow of ping requests/replies * @f: Generic flow information diff --git a/inany.h b/inany.h index b02c289..c7de094 100644 --- a/inany.h +++ b/inany.h @@ -9,6 +9,11 @@ #ifndef INANY_H #define INANY_H
+#include
+ +#include "ip.h" +#include "siphash.h" + struct siphash_state; /** union inany_addr - Represents either an IPv4 or IPv6 address diff --git a/ip.h b/ip.h index a8043c2..3be2d4e 100644 --- a/ip.h +++ b/ip.h @@ -9,6 +9,8 @@ #include
#include +#include "util.h" + #define IN4_IS_ADDR_UNSPECIFIED(a) \ (((struct in_addr *)(a))->s_addr == htonl_constant(INADDR_ANY)) #define IN4_IS_ADDR_BROADCAST(a) \ diff --git a/linux_dep.h b/linux_dep.h index 89e590c..3f8184b 100644 --- a/linux_dep.h +++ b/linux_dep.h @@ -7,6 +7,9 @@ #ifndef LINUX_DEP_H #define LINUX_DEP_H
+#include
+#include + /* struct tcp_info_linux - Information from Linux TCP_INFO getsockopt() * * Largely derived from include/linux/tcp.h in the Linux kernel diff --git a/pif.h b/pif.h index 0f7f667..7c755bd 100644 --- a/pif.h +++ b/pif.h @@ -7,6 +7,10 @@ #ifndef PIF_H #define PIF_H +#include
+ +#include "epoll_type.h" + union inany_addr; union sockaddr_inany; diff --git a/seccomp.sh b/seccomp.sh index 60ebe84..5347586 100755 --- a/seccomp.sh +++ b/seccomp.sh @@ -34,6 +34,11 @@ AUDIT_ARCH="AUDIT_ARCH_$(echo ${ARCH} | tr '[a-z]' '[A-Z]' \
HEADER="/* This file was automatically generated by $(basename ${0}) */
+#include
+#include +#include +#include + #ifndef AUDIT_ARCH_PPC64LE #define AUDIT_ARCH_PPC64LE (AUDIT_ARCH_PPC64 | __AUDIT_ARCH_LE) #endif" diff --git a/siphash.h b/siphash.h index e760236..bbddcac 100644 --- a/siphash.h +++ b/siphash.h @@ -44,6 +44,9 @@ #ifndef SIPHASH_H #define SIPHASH_H +#include
+#include + /** * struct siphash_state - Internal state of siphash calculation */ diff --git a/tap.h b/tap.h index cc780d1..07ca096 100644 --- a/tap.h +++ b/tap.h @@ -6,6 +6,11 @@ #ifndef TAP_H #define TAP_H +#include
+#include + +#include "passt.h" + /** L2_MAX_LEN_PASTA - Maximum frame length for pasta mode (with L2 header) * * The kernel tuntap device imposes a maximum frame size of 65535 including diff --git a/tcp_conn.h b/tcp_conn.h index 21cea10..d4d0139 100644 --- a/tcp_conn.h +++ b/tcp_conn.h @@ -9,6 +9,10 @@ #ifndef TCP_CONN_H #define TCP_CONN_H +#include
+ +#include "flow.h" + /** * struct tcp_tap_conn - Descriptor for a TCP connection (not spliced) * @f: Generic flow information diff --git a/tcp_internal.h b/tcp_internal.h index 518913b..591e58c 100644 --- a/tcp_internal.h +++ b/tcp_internal.h @@ -6,6 +6,11 @@ #ifndef TCP_INTERNAL_H #define TCP_INTERNAL_H +#include
+#include + +#include "util.h" + #define MAX_WS 8 #define MAX_WINDOW (1 << (16 + (MAX_WS))) diff --git a/udp_internal.h b/udp_internal.h index 0a8fe49..64e4577 100644 --- a/udp_internal.h +++ b/udp_internal.h @@ -6,6 +6,9 @@ #ifndef UDP_INTERNAL_H #define UDP_INTERNAL_H
+#include
+#include + #include "tap.h" /* needed by udp_meta_t */ /** diff --git a/util.c b/util.c index a48f727..db27431 100644 --- a/util.c +++ b/util.c @@ -25,6 +25,7 @@ #include
#include #include +#include #include #include "linux_dep.h" -- 2.53.0.371.g1d285c8824-goog
-- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
On Mon, 23 Feb 2026 16:33:32 +1100
David Gibson
On Thu, Feb 19, 2026 at 01:44:54PM -0500, Peter Foley wrote:
Support build systems like bazel that check that headers are self-contained.
Signed-off-by: Peter Foley
There are kind of two schools of thoughts on headers. One is that every header should #include anything it relies on. The other is that headers should #include nothing, and .c files should includde everything they need in the right order. The advantages of the second approach are that it makes it easier to keep #includes in .c files minimal, and makes circular dependencies more obvious and easier to dientanble.
We've kinda sorta been using approach two in passt, but not entirely, and honestly, it's not really working.
I would argue it *is* pretty much working, because it builds without warnings against glibc and musl, with several versions of gcc and Clang, on a large number of distributions and architectures, which is what it needs to do. There are currently two warnings with (unreleased) gcc 16-ish and glibc, I still have to post patches for them, but they have nothing to do with includes. That being said, sure, it's not either approach and admittedly kind of arbitrary and rather messy.
So I'm happy to convert to the former approach. However, if we're adding #includes in the headers so they're self contained, then we should be able to also *remove* a bunch of #includes from .c files (and other .h files) which were previously only there to satisfy the indirect dependencies.
Just for clarity, while I agree, this patch does *not* magically make that Peter's job. :) I'd say that making it build with Bazel is more useful at this stage so I would happily accept this patch by itself (I just need to find a moment to try out builds on musl and on a couple of distributions, first). The cleanup you propose can also be done independently at a later point, also because I'm fairly sure there are a bunch of left-over includes (also/mostly from myself) even before this change. Note that this kind of cleanup would also take a bit of testing that we currently can't automate, for example building against musl on Alpine or Void Linux. -- Stefano
On Sat, Feb 21, 2026 at 12:57 PM Stefano Brivio
It looks obviously correct to me, but I still have a question: do you happen to have a Bazel BUILD file somewhere (we could also add it to passt's contrib/ if it's not in any other repository) to check future changes against it?
The primary BUILD file is in Google's internal repository, so I can't share that. An OSS bazel version looks like https://github.com/pefoley2/passt/commit/4f89da6f05c84c9f171689541fd81549b48... Unfortunately in my quick testing, the OSS bazel build doesn't actually catch the same layering check violations that Google's internal "Blaze" variant of bazel does. So I'm not sure how helpful it would be.
On Mon, Feb 23, 2026 at 11:45 AM Peter Foley
The primary BUILD file is in Google's internal repository, so I can't share that. An OSS bazel version looks like https://github.com/pefoley2/passt/commit/4f89da6f05c84c9f171689541fd81549b48... Unfortunately in my quick testing, the OSS bazel build doesn't actually catch the same layering check violations that Google's internal "Blaze" variant of bazel does. So I'm not sure how helpful it would be.
I poked at this some more, and clang-include-cleaner seems to be able to do a good job of determining whether the headers compile stand-alone. I had to make some more fixes to get there though: https://github.com/pefoley2/passt/commit/5067d86e567851db24dad515cd36b536272... If you want, I can fold the two "include fixing" commits together and re-send.
On Mon, 23 Feb 2026 12:23:08 -0500
Peter Foley
On Mon, Feb 23, 2026 at 11:45 AM Peter Foley
wrote: The primary BUILD file is in Google's internal repository, so I can't share that. An OSS bazel version looks like https://github.com/pefoley2/passt/commit/4f89da6f05c84c9f171689541fd81549b48... Unfortunately in my quick testing, the OSS bazel build doesn't actually catch the same layering check violations that Google's internal "Blaze" variant of bazel does. So I'm not sure how helpful it would be.
I poked at this some more, and clang-include-cleaner seems to be able to do a good job of determining whether the headers compile stand-alone. I had to make some more fixes to get there though: https://github.com/pefoley2/passt/commit/5067d86e567851db24dad515cd36b536272...
By the way, we already run clang-tidy tests ('make clang-tidy') as part of our tests (test/build/static_checkers.sh). Would it be just a matter of enabling the misc-include-cleaner in the list of tests we give clang-tidy from the Makefile: https://clang.llvm.org/extra/clang-tidy/checks/misc/include-cleaner.html ? I haven't tried.
If you want, I can fold the two "include fixing" commits together and re-send.
Yes, thanks, that would be appreciated. I would first try to settle on a convenient way to keep Blaze/Bazel happy for the future, though. -- Stefano
On Mon, Feb 23, 2026 at 12:35 PM Stefano Brivio
By the way, we already run clang-tidy tests ('make clang-tidy') as part of our tests (test/build/static_checkers.sh).
Would it be just a matter of enabling the misc-include-cleaner in the list of tests we give clang-tidy from the Makefile:
https://clang.llvm.org/extra/clang-tidy/checks/misc/include-cleaner.html
? I haven't tried.
It appears so, a local change to pass -checks=misc-include-cleaner to clang-tidy resulted in a ton of errors like: /usr/local/google/home/pefoley/passt/vu_common.c:277:2: error: no header providing "iov_from_buf" is directly included [misc-include-cleaner,-warnings-as-errors] 277 | iov_from_buf(in_sg, elem_cnt, VNET_HLEN, buf, total); | ^ /usr/local/google/home/pefoley/passt/vu_common.c:301:15: error: no header providing "ETH_ZLEN" is directly included [misc-include-cleaner,-warnings-as-errors] 9 | if (l2len >= ETH_ZLEN) | ^ /usr/local/google/home/pefoley/passt/vu_common.c:304:2: error: no header providing "memset" is directly included [misc-include-cleaner,-warnings-as-errors] 9 | memset((char *)iov->iov_base + iov->iov_len, 0, ETH_ZLEN - l2len);
If you want, I can fold the two "include fixing" commits together and re-send.
Yes, thanks, that would be appreciated. I would first try to settle on a convenient way to keep Blaze/Bazel happy for the future, though.
As I mentioned earlies, Bazel appears to be happy withough the include fixes, it's just Google's internal Blaze varient that has some kind of stricter checking that falls over. I can send the change out for supporting the Bazel build, but I think using misc-include-cleaner would be a better plan.
-- Stefano
Support build systems like bazel that check that headers are
self-contained.
Also update includes so that clang-include-cleaner succeeds.
Tested with:
clang-include-cleaner-19 --extra-arg=-D_GNU_SOURCE --extra-arg=-DPAGE_SIZE=4096 --extra-arg=-DVERSION=\"git\" --extra-arg=-DHAS_GETRANDOM *.h *.c
Signed-off-by: Peter Foley
On Mon, 23 Feb 2026 13:08:07 -0500
Peter Foley
On Mon, Feb 23, 2026 at 12:35 PM Stefano Brivio
wrote: By the way, we already run clang-tidy tests ('make clang-tidy') as part of our tests (test/build/static_checkers.sh).
Would it be just a matter of enabling the misc-include-cleaner in the list of tests we give clang-tidy from the Makefile:
https://clang.llvm.org/extra/clang-tidy/checks/misc/include-cleaner.html
? I haven't tried.
It appears so, a local change to pass -checks=misc-include-cleaner to clang-tidy resulted in a ton of errors like: /usr/local/google/home/pefoley/passt/vu_common.c:277:2: error: no header providing "iov_from_buf" is directly included
[...]
Hmm, "nice". I guess we should find out if it's reasonable / doable to "fix" all those.
If you want, I can fold the two "include fixing" commits together and re-send.
Yes, thanks, that would be appreciated. I would first try to settle on a convenient way to keep Blaze/Bazel happy for the future, though.
As I mentioned earlies, Bazel appears to be happy withough the include fixes, it's just Google's internal Blaze varient that has some kind of stricter checking that falls over.
Oh, I didn't understand, I thought Bazel reported a non-empty subset of the failures from Blaze.
I can send the change out for supporting the Bazel build, but I think using misc-include-cleaner would be a better plan.
Yeah, I think so too... as long as it's not hundreds of additional warnings / fixes we need to take care of, it's definitely less effort and should be less clunky too. -- Stefano
On Mon, Feb 23, 2026 at 2:05 PM Stefano Brivio
Hmm, "nice". I guess we should find out if it's reasonable / doable to "fix" all those.
I tried just doing clang-include-cleaner --edit, but it's
unfortunately c++ centric, so it added a bunch of stuff like <cstdint> I can try manually fixing that up and seeing what happens.
-- Stefano
On Mon, 23 Feb 2026 15:22:20 -0500
Peter Foley
On Mon, Feb 23, 2026 at 2:05 PM Stefano Brivio
wrote: Hmm, "nice". I guess we should find out if it's reasonable / doable to "fix" all those.
I tried just doing clang-include-cleaner --edit, but it's unfortunately c++ centric, so it added a bunch of stuff like <cstdint> I can try manually fixing that up and seeing what happens.
By the way, I won't have a chance to try this before a couple of days, if needed, but another thought: if we end up adding/changing hundreds of include lines as a result, maybe the cleanup David mentioned would actually be in scope at that point, even from a mere perspective of "noise" we would add, or effort you're spending anyway (let's make it fully worth it I'd say). In any case we could keep a clean clang-include-cleaner output as second step. I think the priorities here should be 1. keep/make things working for everybody while 2. avoiding the risk of recurring fix-ups for future changes and 3. make things pretty/readable/elegant, exactly in this order. If we can tackle all of them together, great, otherwise we can take care of 1. first, and 2. and 3. later. -- Stefano
On Mon, Feb 23, 2026 at 3:47 PM Stefano Brivio
By the way, I won't have a chance to try this before a couple of days, if needed, but another thought: if we end up adding/changing hundreds of include lines as a result, maybe the cleanup David mentioned would actually be in scope at that point, even from a mere perspective of "noise" we would add, or effort you're spending anyway (let's make it fully worth it I'd say).
I tried running clang-include-cleaner and then massaging it to not include
c++ only headers or stuff from bits/
That wound up with:
64 files changed, 349 insertions(+), 189 deletions(-)
Unfortunatly include-cleaner isn't smart enough to handle things like
#include
On Mon, 23 Feb 2026 16:37:54 -0500
Peter Foley
On Mon, Feb 23, 2026 at 3:47 PM Stefano Brivio
wrote: By the way, I won't have a chance to try this before a couple of days, if needed, but another thought: if we end up adding/changing hundreds of include lines as a result, maybe the cleanup David mentioned would actually be in scope at that point, even from a mere perspective of "noise" we would add, or effort you're spending anyway (let's make it fully worth it I'd say).
I tried running clang-include-cleaner and then massaging it to not include c++ only headers or stuff from bits/ That wound up with: 64 files changed, 349 insertions(+), 189 deletions(-)
Unfortunatly include-cleaner isn't smart enough to handle things like #include
instead of So absent adding pragma annotations to glibc headers, I'm not sure a clean clang-include-cleaner check is possible.
We could always add suppressions for clang-tidy checks, we already have a bunch, see NOLINTNEXTLINE directives in the code.
That diff is https://github.com/pefoley2/passt/commit/6ae0bcb2bbdc10384346dda547db60f80c8... . I can send it as a proper patch as well if you're interested, but it's a lot of churn and I'm not sure how to prevent back-sliding...
Ouch... yeah. Let me have another look tomorrow (Tuesday) but I think it only makes sense if we use that as a chance to entirely switch to approach #2 David was mentioning (minus perhaps some exceptions), including all the related clean-ups. I'm totally for it by the way, if you can take care of it. Otherwise I'd recommend sticking to a more conservative approach for the moment being. -- Stefano
On Mon, Feb 23, 2026 at 05:32:01PM +0100, Stefano Brivio wrote:
On Mon, 23 Feb 2026 16:33:32 +1100 David Gibson
wrote: On Thu, Feb 19, 2026 at 01:44:54PM -0500, Peter Foley wrote:
Support build systems like bazel that check that headers are self-contained.
Signed-off-by: Peter Foley
There are kind of two schools of thoughts on headers. One is that every header should #include anything it relies on. The other is that headers should #include nothing, and .c files should includde everything they need in the right order. The advantages of the second approach are that it makes it easier to keep #includes in .c files minimal, and makes circular dependencies more obvious and easier to dientanble.
We've kinda sorta been using approach two in passt, but not entirely, and honestly, it's not really working.
I would argue it *is* pretty much working, because it builds without warnings against glibc and musl, with several versions of gcc and Clang, on a large number of distributions and architectures, which is what it needs to do.
Ok, let me qualify that. I mean that I frequently hit minor irritations related to not-self-contained headers, and I'm not really feeling the benefits of the approach.. That is to say, I don't feel like the no-indirect-includes approach is working in the sense of providing benefits to outweigh going the other direction.
There are currently two warnings with (unreleased) gcc 16-ish and glibc, I still have to post patches for them, but they have nothing to do with includes.
That being said, sure, it's not either approach and admittedly kind of arbitrary and rather messy.
Right.
So I'm happy to convert to the former approach. However, if we're adding #includes in the headers so they're self contained, then we should be able to also *remove* a bunch of #includes from .c files (and other .h files) which were previously only there to satisfy the indirect dependencies.
Just for clarity, while I agree, this patch does *not* magically make that Peter's job. :)
Heh, fair enough.
I'd say that making it build with Bazel is more useful at this stage so I would happily accept this patch by itself (I just need to find a moment to try out builds on musl and on a couple of distributions, first).
Also fair enough.
The cleanup you propose can also be done independently at a later point, also because I'm fairly sure there are a bunch of left-over includes (also/mostly from myself) even before this change.
Note that this kind of cleanup would also take a bit of testing that we currently can't automate, for example building against musl on Alpine or Void Linux.
-- Stefano
-- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
On Mon, Feb 23, 2026 at 01:08:07PM -0500, Peter Foley wrote:
On Mon, Feb 23, 2026 at 12:35 PM Stefano Brivio
wrote: By the way, we already run clang-tidy tests ('make clang-tidy') as part of our tests (test/build/static_checkers.sh).
Would it be just a matter of enabling the misc-include-cleaner in the list of tests we give clang-tidy from the Makefile:
https://clang.llvm.org/extra/clang-tidy/checks/misc/include-cleaner.html
? I haven't tried.
It appears so, a local change to pass -checks=misc-include-cleaner to clang-tidy resulted in a ton of errors like: /usr/local/google/home/pefoley/passt/vu_common.c:277:2: error: no header providing "iov_from_buf" is directly included [misc-include-cleaner,-warnings-as-errors] 277 | iov_from_buf(in_sg, elem_cnt, VNET_HLEN, buf, total); | ^ /usr/local/google/home/pefoley/passt/vu_common.c:301:15: error: no header providing "ETH_ZLEN" is directly included [misc-include-cleaner,-warnings-as-errors] 9 | if (l2len >= ETH_ZLEN) | ^ /usr/local/google/home/pefoley/passt/vu_common.c:304:2: error: no header providing "memset" is directly included [misc-include-cleaner,-warnings-as-errors] 9 | memset((char *)iov->iov_base + iov->iov_len, 0, ETH_ZLEN - l2len);
Unfortunately, I suspect this isn't going to work out. It may do some of the checks we want here, but unfortunately it makes some very silly warnings in relation to the standard library, which is why we disabled it in the first place. See commit 3be9e0010ea7329ae0f3707f67ac4cf0bac13d54 I guess we should retry and see if the latest LLVM is better about this, though.
If you want, I can fold the two "include fixing" commits together and re-send.
Yes, thanks, that would be appreciated. I would first try to settle on a convenient way to keep Blaze/Bazel happy for the future, though.
As I mentioned earlies, Bazel appears to be happy withough the include fixes, it's just Google's internal Blaze varient that has some kind of stricter checking that falls over. I can send the change out for supporting the Bazel build, but I think using misc-include-cleaner would be a better plan.
-- Stefano
-- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
On Tue, 24 Feb 2026 16:43:13 +1100
David Gibson
On Mon, Feb 23, 2026 at 01:08:07PM -0500, Peter Foley wrote:
On Mon, Feb 23, 2026 at 12:35 PM Stefano Brivio
wrote: By the way, we already run clang-tidy tests ('make clang-tidy') as part of our tests (test/build/static_checkers.sh).
Would it be just a matter of enabling the misc-include-cleaner in the list of tests we give clang-tidy from the Makefile:
https://clang.llvm.org/extra/clang-tidy/checks/misc/include-cleaner.html
? I haven't tried.
It appears so, a local change to pass -checks=misc-include-cleaner to clang-tidy resulted in a ton of errors like: /usr/local/google/home/pefoley/passt/vu_common.c:277:2: error: no header providing "iov_from_buf" is directly included [misc-include-cleaner,-warnings-as-errors] 277 | iov_from_buf(in_sg, elem_cnt, VNET_HLEN, buf, total); | ^ /usr/local/google/home/pefoley/passt/vu_common.c:301:15: error: no header providing "ETH_ZLEN" is directly included [misc-include-cleaner,-warnings-as-errors] 9 | if (l2len >= ETH_ZLEN) | ^ /usr/local/google/home/pefoley/passt/vu_common.c:304:2: error: no header providing "memset" is directly included [misc-include-cleaner,-warnings-as-errors] 9 | memset((char *)iov->iov_base + iov->iov_len, 0, ETH_ZLEN - l2len);
Unfortunately, I suspect this isn't going to work out. It may do some of the checks we want here, but unfortunately it makes some very silly warnings in relation to the standard library, which is why we disabled it in the first place. See commit 3be9e0010ea7329ae0f3707f67ac4cf0bac13d54
Ouch, right, I had forgotten about that.
I guess we should retry and see if the latest LLVM is better about this, though.
I guess: https://github.com/pefoley2/passt/commit/6ae0bcb2bbdc10384346dda547db60f80c8... makes that mostly pass with a recent LLVM version? If we need a dozen of suppressions (maybe even 20-30?) I would say it's sustainable, but more than that and it will start looking messy. -- Stefano
On Tue, Feb 24, 2026 at 4:33 AM Stefano Brivio
I guess:
https://github.com/pefoley2/passt/commit/6ae0bcb2bbdc10384346dda547db60f80c8...
makes that mostly pass with a recent LLVM version? If we need a dozen of suppressions (maybe even 20-30?) I would say it's sustainable, but more than that and it will start looking messy.
Ideally glibc would add the necessary annotations to their bits/ headers to make include-cleaner do the right thing, but I'm not sure whether they'd want to do that in the first place. And even if they did, it would take a while for a "fixed" version to roll out. Let alone other libc implementations like musl.
I suppose another track would be to add special-case logic to clang-tidy to not recommend bits headers, but I don't know if the LLVM maintainers would like that either.
On Tue, 24 Feb 2026 11:49:13 -0500
Peter Foley
On Tue, Feb 24, 2026 at 4:33 AM Stefano Brivio
wrote: I guess:
https://github.com/pefoley2/passt/commit/6ae0bcb2bbdc10384346dda547db60f80c8...
makes that mostly pass with a recent LLVM version? If we need a dozen of suppressions (maybe even 20-30?) I would say it's sustainable, but more than that and it will start looking messy.
Ideally glibc would add the necessary annotations to their bits/ headers to make include-cleaner do the right thing, but I'm not sure whether they'd want to do that in the first place. And even if they did, it would take a while for a "fixed" version to roll out. Let alone other libc implementations like musl.
I suppose another track would be to add special-case logic to clang-tidy to not recommend bits headers, but I don't know if the LLVM maintainers would like that either.
Right, none of the options above look like reasonable short-term goals. What I was suggesting was to sprinkle the code with beauties such as: /* NOLINTNEXTLINE(misc-include-cleaner) */ before each "offending" include line... assuming it works, and assuming we need perhaps 20-30 of them. But if it's a lot more, then that's not a reasonable option either. -- Stefano
On Tue, Feb 24, 2026 at 12:53 PM Stefano Brivio
What I was suggesting was to sprinkle the code with beauties such as:
/* NOLINTNEXTLINE(misc-include-cleaner) */
Unfortunatly it needs to go before the usage, not the include. e.g. /usr/local/google/home/pefoley/passt/util.c:122:21: error: no header providing "SOL_SOCKET" is directly included [misc-include-cleaner,-warnings-as-errors] 15 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(y))) | ^ /usr/local/google/home/pefoley/passt/util.c:122:33: error: no header providing "SO_REUSEADDR" is directly included [misc-include-cleaner,-warnings-as-errors] 122 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(y))) | ^ /usr/local/google/home/pefoley/passt/util.c:143:34: error: no header providing "SO_BINDTODEVICE" is directly included [misc-include-cleaner,-warnings-as-errors] 143 | if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, | ^ /usr/local/google/home/pefoley/passt/util.c:323:32: error: no header providing "SO_SNDBUF" is directly included [misc-include-cleaner,-warnings-as-errors] 323 | if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &v, sizeof(v)) || | ^ /usr/local/google/home/pefoley/passt/util.c:329:32: error: no header providing "SO_RCVBUF" is directly included [misc-include-cleaner,-warnings-as-errors] 329 | if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &v, sizeof(v)) || | ^ /usr/local/google/home/pefoley/passt/util.c:855:42: error: no header providing "iovec" is directly included [misc-include-cleaner,-warnings-as-errors] 15 | int write_remainder(int fd, const struct iovec *iov, size_t iovcnt, size_t skip) | ^ /usr/local/google/home/pefoley/passt/util.c:1070:15: error: no header providing "option" is directly included [misc-include-cleaner,-warnings-as-errors] 15 | const struct option optfd[] = { { "fd", required_argument, NULL, 'F' }, | ^ /usr/local/google/home/pefoley/passt/util.c:1070:42: error: no header providing "required_argument" is directly included [misc-include-cleaner,-warnings-as-errors] 1070 | const struct option optfd[] = { { "fd", required_argument, NULL, 'F' }, | ^ /usr/local/google/home/pefoley/passt/util.c:1077:10: error: no header providing "getopt_long" is directly included [misc-include-cleaner,-warnings-as-errors] 1077 | name = getopt_long(argc, argv, "-:F:", optfd, NULL); | ^ /usr/local/google/home/pefoley/passt/util.c:1081:16: error: no header providing "optarg" is directly included [misc-include-cleaner,-warnings-as-errors] 15 | fd = strtol(optarg, NULL, 0); | ^
before each "offending" include line... assuming it works, and assuming we need perhaps 20-30 of them. But if it's a lot more, then that's not a reasonable option either.
I get "72 warnings treated as errors" when running clang-tidy with my current set of patches.
-- Stefano
On Tue, 24 Feb 2026 13:52:04 -0500
Peter Foley
On Tue, Feb 24, 2026 at 12:53 PM Stefano Brivio
wrote: What I was suggesting was to sprinkle the code with beauties such as:
/* NOLINTNEXTLINE(misc-include-cleaner) */
Unfortunatly it needs to go before the usage, not the include.
Ah, right, of course.
before each "offending" include line... assuming it works, and assuming we need perhaps 20-30 of them. But if it's a lot more, then that's not a reasonable option either.
I get "72 warnings treated as errors" when running clang-tidy with my current set of patches.
Ugh. Yet another alternative could be to enable misc-include-cleaner for headers only, which would probably need a separate invocation of clang-tidy. I'm not sure if that will work at all though. If it doesn't, I'm out of ideas... maybe we should simply go back to your original patch, in that case, and you'll just get to "fix" things as they break (hopefully infrequently) in the future. -- Stefano
Ugh. Yet another alternative could be to enable misc-include-cleaner for headers only, which would probably need a separate invocation of clang-tidy.
I'm not sure if that will work at all though. If it doesn't, I'm out of ideas... maybe we should simply go back to your original patch, in that case, and you'll just get to "fix" things as they break (hopefully infrequently) in the future.
I tried that, it didn't go well either: /usr/local/google/home/pefoley/passt/util.h:140:5: error: no header
On Tue, Feb 24, 2026 at 3:03 PM Stefano Brivio
-- Stefano
On Tue, 24 Feb 2026 15:24:57 -0500
Peter Foley
On Tue, Feb 24, 2026 at 3:03 PM Stefano Brivio
wrote: Ugh. Yet another alternative could be to enable misc-include-cleaner for headers only, which would probably need a separate invocation of clang-tidy.
I'm not sure if that will work at all though. If it doesn't, I'm out of ideas... maybe we should simply go back to your original patch, in that case, and you'll just get to "fix" things as they break (hopefully infrequently) in the future.
I tried that, it didn't go well either: /usr/local/google/home/pefoley/passt/util.h:140:5: error: no header providing "__BYTE_ORDER" is directly included [misc-include-cleaner,-warnings-as-errors]
9 | #if __BYTE_ORDER == __BIG_ENDIAN
| ^
/usr/local/google/home/pefoley/passt/util.h:140:21: error: no header providing "__BIG_ENDIAN" is directly included [misc-include-cleaner,-warnings-as-errors]
140 | #if __BYTE_ORDER == __BIG_ENDIAN
| ^
/usr/local/google/home/pefoley/passt/util.h:241:42: error: no header providing "iovec" is directly included [misc-include-cleaner,-warnings-as-errors]
9 | int write_remainder(int fd, const struct iovec *iov, size_t iovcnt, size_t skip); | ^
/usr/local/google/home/pefoley/passt/util.h:254:35: error: no header providing "sa_family_t" is directly included [misc-include-cleaner,-warnings-as-errors]
9 | static inline const char *af_name(sa_family_t af)
Oh... fun.
I'm inclined to forget about trying to fix everything and just do the minimal set of changes to make the tooling happy with parsing the headers.
Yeah, at this point I'd totally support that. -- Stefano
On Tue, Feb 24, 2026 at 4:18 PM Stefano Brivio
I'm inclined to forget about trying to fix everything and just do the minimal set of changes to make the tooling happy with parsing the headers.
Yeah, at this point I'd totally support that.
Does the most recent patch I sent look good to apply? That should be the "minimal" include happiness version.
On Tue, Feb 24, 2026 at 09:03:18PM +0100, Stefano Brivio wrote:
On Tue, 24 Feb 2026 13:52:04 -0500 Peter Foley
wrote: On Tue, Feb 24, 2026 at 12:53 PM Stefano Brivio
wrote: What I was suggesting was to sprinkle the code with beauties such as:
/* NOLINTNEXTLINE(misc-include-cleaner) */
Unfortunatly it needs to go before the usage, not the include.
Ah, right, of course.
before each "offending" include line... assuming it works, and assuming we need perhaps 20-30 of them. But if it's a lot more, then that's not a reasonable option either.
I get "72 warnings treated as errors" when running clang-tidy with my current set of patches.
Ugh. Yet another alternative could be to enable misc-include-cleaner for headers only, which would probably need a separate invocation of clang-tidy.
I'm not sure if that will work at all though. If it doesn't, I'm out of ideas... maybe we should simply go back to your original patch, in that case, and you'll just get to "fix" things as they break (hopefully infrequently) in the future.
Kind if what we want is to apply the check in relation to local "" headers, but not <> system headers. Unfortunately, I don't know if there's any way to do that. -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
On Mon, 23 Feb 2026 13:11:19 -0500
Peter Foley
Support build systems like bazel that check that headers are self-contained.
Also update includes so that clang-include-cleaner succeeds.
Tested with: clang-include-cleaner-19 --extra-arg=-D_GNU_SOURCE --extra-arg=-DPAGE_SIZE=4096 --extra-arg=-DVERSION=\"git\" --extra-arg=-DHAS_GETRANDOM *.h *.c
Signed-off-by: Peter Foley
Tested some more (especially with musl), and applied, thanks. At this point, with David's series applied as well, things should build cleanly for you. -- Stefano
participants (3)
-
David Gibson
-
Peter Foley
-
Stefano Brivio