-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Run codebase through IWYU and add a CI check. ~7-10% improvements to build times. #79631
Conversation
I'll keep track of code size throughout this IWYU endeavor. Two metrics: 1) include size, as measured by `make include` -> `cat *.inc | wc` 2) total preprocessed (post-processed?) source size as measured by `clang -E` -> `cat * | wc` All numbers are for RELEASE=1 SOUND=1 TILES=1 BACKTRACE=1 LOCALIZE=1 build on linux (WSL, ubuntu 24.04) These might get slightly off if I end up rebasing the work (which I hope I won't have to), but should capture the spirit of the change. As of right now, before any contentful edits: Code size: includes: cat obj/tiles/*.inc | wc 288068 576136 17898260 cat tests/obj/tiles/*.inc | wc 171408 342816 10682390 post-processed source (clang -E): ./make_preproc.sh src/ 68567896 177775140 2134075721 ./make_preproc.sh tests/ 40671408 106495252 1283817257
python3 ~/github/include-what-you-use/iwyu_tool.py -j5 -p build $( find src/ tests/ -maxdepth 1 -name '*.cpp' | grep -v -f tools/iwyu/bad_files.txt ) -- -Xiwyu --comment_style=long -Xiwyu - -max_line_length=1000 -Xiwyu --cxx17ns -Xiwyu --mapping_file=../tools/iwyu/cata.imp | tee out/iwyu/f-a-01.txt > /dev/null followed by cat out/iwyu/f-a-02.txt | python3 ~/github/include-what-you-use/fix_includes.py --reorder --nosafe_headers followed by manual fixups of <stddef.h> -> <cstddef> and similar. tests/generic_factory_test.cpp gets mangled very badly (IWYU bug) so it's excluded from the list. Code size: includes: $ cat obj/tiles/*.inc | wc 288068 576136 17898260 $ cat tests/obj/tiles/*.inc | wc 167044 334088 10465766 post-processed source (clang -E): ./make_preproc.sh src/ 68567896 177775140 2134075721 ./make_preproc.sh tests/ 39341957 102891720 1243323710
Code size: includes: $ cat obj/tiles/*.inc | wc 288068 576136 17898260 $ cat tests/obj/tiles/*.inc | wc 167044 334088 10465935 post-processed source (clang -E): ./make_preproc.sh src/ 68567896 177775140 2134075721 ./make_preproc.sh tests/ 39342173 102892081 1243328627
I'm not quite sure why IWYU stumbles over these but clang builds the files totally fine, but oh well. Code size: includes: $ cat obj/tiles/*.inc | wc 289205 578410 17936655 $ cat tests/obj/tiles/*.inc | wc 168063 336126 10504341 post-processed source (clang -E): ./make_preproc.sh src/ 68951553 178823261 2145455631 ./make_preproc.sh tests/ 39688267 103830363 1253702866
because having multiple files (re-)define the same thing is confusing and bugprone. Note how activity_item_handling.cpp definiton was slightly different from the rest (and also never used) Code size: includes: $ cat obj/tiles/*.inc | wc 289634 579268 17954860 $ cat tests/obj/tiles/*.inc | wc 168196 336392 10510740 post-processed (clang -E): cat ./out/pp/src/* | wc 69096536 179224518 2150572312 cat ./out/pp/tests/* | wc 40499273 106027071 1277878587
... three times, until it stops making new suggestions. Run with --safe_headers (default) (i.e. headers can only get new includes added, but can't get anything removed) The code does not compile in current state (kinda expected), manual fixups will follow. --nosafe_headers commit would also follow afterwards The "simple" files are those that don't have any sort of define/if defined/ifndef conditional compilation in them. Just plain old c++ with no preprocessor. Code size: includes: $ cat obj/tiles/*.inc | wc 290436 580872 17972230 $ cat tests/obj/tiles/*.inc | wc 168196 336392 10510740 post-processed (clang -E): cat ./out/pp/src/* | wc 69365093 179919823 2157445134 cat ./out/pp/tests/* | wc 40499273 106027071 1277878587 The code size increase is expected due to --safe_headers
Code size: includes: $ cat obj/tiles/*.inc | wc 290441 580882 17972409 $ cat tests/obj/tiles/*.inc | wc 168196 336392 10510740 post-processed (clang -E): cat ./out/pp/src/* | wc 69365837 179921404 2157462252 cat ./out/pp/tests/* | wc 40499273 106027071 1277878587
Code most likely doesn't build anymore, will fix. Code size: includes: $ cat obj/tiles/*.inc | wc 276953 553906 17327802 $ cat tests/obj/tiles/*.inc | wc 162948 325896 10274699 post-processed source (clang -E): ./make_preproc.sh src/ 65627805 169571983 2041450272 ./make_preproc.sh tests/ 38287614 99918518 1211467858
.. and ensure iwyu is still happy with this (i.e. it's not suggesting i change anything else) Code size: includes: $ cat obj/tiles/*.inc | wc 278246 556492 17375633 $ cat tests/obj/tiles/*.inc | wc 163748 327496 10306945 post-processed source (clang -E): ./make_preproc.sh src/ 65903052 170378728 2049783276 ./make_preproc.sh tests/ 38434368 100326839 1215848465
Code size: includes: $ cat obj/tiles/*.inc | wc 278247 556494 17375710 $ cat tests/obj/tiles/*.inc | wc 163745 327490 10307041 post-processed source (clang -E): ./make_preproc.sh src/ 65903054 170378741 2049783477 ./make_preproc.sh tests/ 38434408 100326802 1215849078
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Auto-requesting reviews from non-collaborators: @jbytheway @wapcaplet @andrei8l
I can say up front that based on the magnitude of improvements in preprocessed files and build times, and the CI and opt-in workflows being included, I AM interested in getting this merged. |
The github web UI just yeets itself off a cliff on this PR. Can we PR some of the noncontroversial changes separately to help ease this in (eg. the c header modernization stuff can be trivally merged by itself). |
Reviewing this commit-by-commit should help. There only three kinds of changes here:
I'm not sure submitting any of those separately would help enough. edit: well, i guess i can move out 28db853 and 0c8954a . But, again, i don't think this is quite enough to make things beter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some quick review comments before you do too much more. I got down to around src/construction.cpp
and find it unlikely I'll see something else generic to suggest.
Also maybe add to flexbuffer_json.h
although I haven't seen it show up as an unnecessary addition much anywhere.
#include "json_error.h" // IWYU pragma: export
Minor issue i noticed: if there are no fatal parse errors, then IWYU exits with code 0 even if it made suggestions on how to adjust includes (see the current CI run: https://github.com/CleverRaven/Cataclysm-DDA/actions/runs/13272432900/job/37054800929?pr=79631) Easily fixable, but I shall declare this as a feature for now, for the transition period. |
Although I can't imagine how something might decide to barf at this point (if anything the Windows build would be most susceptible to header reordering), I'm sitting on the builds until they go green before merging. |
Summary
None
Purpose of change
(This is a revival/continuation of #79239 following the advice from the comments therein.)
IWYU is a tool that checks that all the symbols used in C++ code are also actively
#include
d. This is considered to be a good thing, some specific benefits being listed in their FAQThis PR fixes [a decent chunk of the code] to include what it uses.
It also adds a CI job aimed to maintain the correct includes going forward, so as to prevent backsliding and the need for these massive sweeping PRs.
Describe the solution
"Easy" here meaning "everything under tests/ and those files under src/ that have no
define
shenanigans in them whatsoever"Code size
src/
tests/
clang -E
src/
clang -E
test/
start to finish
Here:
make includes && cat obj/*.inc | wc -l
- i.e. the total size of recorded include.. paths? relations? dependencies? idk how to word this properly.clang -E
column representes, rougjlyclang -E src/*.cpp | wc -l
, i.e. the total size of the codebase after the preprocessor has run and#include
s were, well, included.The
make includes
was run wtih TILES=1 SOUND=1 RELEASE=1 LOCALIZE=1 BACKTRACE=1, theclang -E
was run with flags from the equivalent cmake build. On WSL Ubuntu 24.04Build times
I have measured build times without the change (matrix win) and with it (matrix win), basing on 9492421 with ccache disabled. Results:
Looks like 7-10% build time improvement (although that's perhaps not too impressive when it translates to only a couple of minutes absolute difference).
Future work
There is ample opportunity to improve:
The IWYU CI job currently runs on every PR, even json-only, but that would be easy to fix.Edit: should be fixed now#include <stddef.h>
forsize_t
which immediately triggers clang-tidy complaint to modernizestddef.h
tocstddef
. This is not fixable with IWYU config, but perhaps we can post-process its output and tweak the error message to the correct one.Testing
CI
Additional context
Edit: Resolved, thanks Kevin!
There are pre-existing merge conflicts. I don't particularly want to waste more time on this if this PR is not something that's desired (because based on the previous interaction, I'm still not sure whether it is), so I won't be fixing those until there is some form of approval from whoever is willing to actually merge it.(and also if there are requests to change the CI, it'd be easier to work on that first, and only then, after said requests are satisfied, fix the conflicts)
I don't have a PR with a failing IWYU CI handy anymore, but this is what the logs look like when it does make suggestions: https://github.com/moxian/Cataclysm-DDA/actions/runs/13210360655
For reviewers: This is perhaps more feasible to review commit-by-commit. I kept the mechanical changes separate from the manual ones, although I'm still not sure if that helps with the review.
CI status in my fork until (until CI here catches up) - moxian#22 ; https://github.com/moxian/Cataclysm-DDA/pull/22/checks?check_run_id=36989468855
If this PR is merged, then other PRs would likely get merge conflicted. I would suggest those accept all the headers, and ignore the IWYU suggestions/breakage to get unblocked, since it can get confusing. It can be fixed in a separate PR later.