IWYU documentation is outdated, incomplete, and lacks guidance

The documentation on IWYU at https://dev.epicgames.com/documentation/unreal\-engine/include\-what\-you\-use\-iwyu\-for\-unreal\-engine\-programming is outdated and has several things that are wrong or incomplete now. I want to point some of these out, and also ask some questions that I wish that page clarified.

  1. The page still mentions `bEnforceIWYU`, but that should be `IWYUSupport = IWYUSupport.Full;` now, which is also the default. Or if they’re both used, it should be in addition.
  2. It doesn’t mention anything about compiling your module with `-IncludeHeaders`, which is one of the main things you can do besides running IWYUMode to make sure your headers actually include what they use. It should say that whether this flag does anything for your module is dependent on `IWYUSupport`.
  3. There’s no mention of `Target.bWarnAboutMonolithicHeadersIncluded`, which we use in our build system. But we found it only compiles when we’re doing nonunity builds where `bUsePCHFiles` is false.
  4. There’s no explainer about how to run UBT’s IWYUMode, which was fixed for Windows in 5.7. This is the only thing that actually enforces IWYU, contrary to the name `bEnforceIWYU`.
  5. There’s no guidance on `UE_INLINE_GENERATED_CPP_BY_NAME`, when to use it, its impact on build times, or the `InlineGeneratedCpps` UBT mode.
  6. Lastly, probably the thing I’m most confused about - the guidance says “Include CoreMinimal.h at the top of each header file.” and “The CoreMinimal.h header file (located under the UE root directory at \Engine\Source\Runtime\Core\Public\CoreMinimal.h) is included first by most of the Engine’s header files.” but CL 23607296/Commit 56431d6 on 1/7/23 removed CoreMinimal.h from dozens of engine files and says “This shaved off 15% of the compile time of small files that has uht markup.” I realize IWYU isn’t specifically a performance improvement, rather a correctness improvement, but can you explain or justify this change?
    1. Why did it improve compile time so much when it has a `#pragma once`?
    2. If it slows down compile times, and some files compile without it, why is it recommended to always include it?
    3. Is there better guidance as to when it’s important to include and when not to, assuming it would compile either way?
    4. Does it even really have anything to do with IWYU, or are you just likely to need types from it, and it’s a simple way to resolve confusing compile errors before they happen? (for things like the _API macros)

We care quite a lot about build hygiene, stability, and opting into things that benefit us in speed and correctness. It has been a multi-year journey figuring this stuff out and trying to do what seems right, but finding that commit I mentioned really made me wonder what the right thing even is. Please provide some guidance if you’re able, and consider updating the documentation to reflect current best practices.

[Attachment Removed]

Hello!

You are correct that the documentation is out of date. I filed a request for the team to review it.

Regarding the 4 points on CoreMinimal.h, this header references most basics types, templates and the math library code. It is fairly heavy on its own and the IWYU mode operates on non-unity builds, ie one compilation unit per cpp file. As such, the “pragma once” directive will not apply as it would when compiling the unity blobs.

It is hard to come up with overall guidance as it really depends on the content of each cpp file. As most team will use the unity mode, this doesn’t really matter as pragma will pick up. The file still needs to be read so unclear how much that costs.

Regards.

Martin

[Attachment Removed]