$npx -y skills add mohitmishra786/low-level-dev-skills --skill include-what-you-useInclude What You Use (IWYU) skill for optimizing C/C++ header includes. Use when reducing compilation cascades, interpreting IWYU reports, applying mapping files, deciding between forward declarations and full includes, or integrating IWYU with CMake. Activates on queries about I
| 1 | # Include What You Use (IWYU) |
| 2 | |
| 3 | ## Purpose |
| 4 | |
| 5 | Guide agents through using IWYU to reduce unnecessary `#include` directives, interpret IWYU reports and mapping files, decide between forward declarations and full includes, and integrate IWYU into CMake builds to reduce compilation cascades in large codebases. |
| 6 | |
| 7 | ## Triggers |
| 8 | |
| 9 | - "How do I use include-what-you-use?" |
| 10 | - "How do I reduce my C++ compilation times by fixing includes?" |
| 11 | - "How do I interpret IWYU output?" |
| 12 | - "Should I use a forward declaration or include?" |
| 13 | - "How do I integrate IWYU with CMake?" |
| 14 | - "What is a compilation cascade and how do I avoid it?" |
| 15 | |
| 16 | ## Workflow |
| 17 | |
| 18 | ### 1. Install and run IWYU |
| 19 | |
| 20 | ```bash |
| 21 | # Install |
| 22 | apt-get install iwyu # Ubuntu/Debian |
| 23 | brew install include-what-you-use # macOS |
| 24 | |
| 25 | # Run on a single file |
| 26 | iwyu -Xiwyu --error main.cpp 2>&1 |
| 27 | |
| 28 | # Run via compile_commands.json |
| 29 | iwyu_tool.py -p build/ src/main.cpp 2>&1 | tee iwyu.log |
| 30 | |
| 31 | # Run on entire project |
| 32 | iwyu_tool.py -p build/ 2>&1 | tee iwyu.log |
| 33 | ``` |
| 34 | |
| 35 | ### 2. CMake integration |
| 36 | |
| 37 | ```cmake |
| 38 | # CMakeLists.txt — use IWYU as include checker during build |
| 39 | find_program(IWYU_PROGRAM NAMES include-what-you-use iwyu) |
| 40 | if(IWYU_PROGRAM) |
| 41 | set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE |
| 42 | ${IWYU_PROGRAM} |
| 43 | -Xiwyu --mapping_file=${CMAKE_SOURCE_DIR}/iwyu.imp |
| 44 | -Xiwyu --no_comments |
| 45 | ) |
| 46 | endif() |
| 47 | ``` |
| 48 | |
| 49 | ```bash |
| 50 | # Build with IWYU analysis |
| 51 | cmake -S . -B build -DCMAKE_CXX_COMPILER=clang++ |
| 52 | cmake --build build 2>&1 | tee iwyu.log |
| 53 | ``` |
| 54 | |
| 55 | ### 3. Interpreting IWYU output |
| 56 | |
| 57 | ```text |
| 58 | main.cpp should add these lines: |
| 59 | #include <string> // for std::string |
| 60 | #include "mylib/widget.h" // for Widget |
| 61 | |
| 62 | main.cpp should remove these lines: |
| 63 | - #include <vector> // lines 5-5 |
| 64 | - #include "internal/detail.h" // lines 8-8 |
| 65 | |
| 66 | The full include-list for main.cpp: |
| 67 | #include <iostream> // for std::cout |
| 68 | #include <string> // for std::string |
| 69 | #include "mylib/widget.h" // for Widget |
| 70 | --- |
| 71 | ``` |
| 72 | |
| 73 | Reading the output: |
| 74 | - **should add**: headers providing symbols used but not yet included |
| 75 | - **should remove**: headers included but whose symbols aren't used directly |
| 76 | - **The full include-list**: what the final header list should look like |
| 77 | |
| 78 | ### 4. Apply IWYU fixes automatically |
| 79 | |
| 80 | ```bash |
| 81 | # fix_include script (comes with IWYU) |
| 82 | fix_include < iwyu.log |
| 83 | |
| 84 | # Options |
| 85 | fix_include --nosafe_headers < iwyu.log # more aggressive — also removes system headers |
| 86 | fix_include --comments < iwyu.log # preserve // comments in includes |
| 87 | fix_include --dry_run < iwyu.log # preview changes without applying |
| 88 | |
| 89 | # Limit to specific files |
| 90 | fix_include --only_re='src/.*\.cpp' < iwyu.log |
| 91 | |
| 92 | # Run and apply in one pipeline |
| 93 | iwyu_tool.py -p build/ 2>&1 | fix_include |
| 94 | ``` |
| 95 | |
| 96 | ### 5. Forward declarations vs full includes |
| 97 | |
| 98 | IWYU prefers forward declarations (class/struct declarations without definition) when the full type isn't needed: |
| 99 | |
| 100 | ```cpp |
| 101 | // full_include.h — DON'T include this if only a pointer is used |
| 102 | #include "widget.h" // full definition: Widget members, vtable, etc. |
| 103 | |
| 104 | // forward_decl.h — OK when Widget* or Widget& is sufficient |
| 105 | class Widget; // forward declaration |
| 106 | void process(Widget *w); // pointer: forward decl is enough |
| 107 | |
| 108 | // When forward declaration is sufficient: |
| 109 | // - Pointer or reference parameter: Widget*, Widget& |
| 110 | // - Return type as pointer: Widget* |
| 111 | // - Base class declared elsewhere (but defined in .cpp) |
| 112 | |
| 113 | // When full include is required: |
| 114 | // - Inheriting from Widget: class MyWidget : public Widget |
| 115 | // - Accessing Widget members: w.field, w.method() |
| 116 | // - Creating Widget instances: Widget w; |
| 117 | // - Sizeof(Widget) |
| 118 | // - Template instantiation: std::vector<Widget> |
| 119 | ``` |
| 120 | |
| 121 | ```cpp |
| 122 | // IWYU-friendly header |
| 123 | #pragma once |
| 124 | class Widget; // forward declare (saves downstream compilation) |
| 125 | |
| 126 | class Container { |
| 127 | Widget *head_; // pointer: forward decl is enough |
| 128 | public: |
| 129 | void add(Widget *w); |
| 130 | Widget *get(int idx); |
| 131 | }; |
| 132 | // Container.cpp includes "widget.h" — only .cpp pays the compile cost |
| 133 | ``` |
| 134 | |
| 135 | ### 6. Mapping files for third-party headers |
| 136 | |
| 137 | IWYU mapping files teach IWYU about indirect includes (where `#include <vector>` is provided by some internal STL header): |
| 138 | |
| 139 | ```python |
| 140 | # iwyu.imp — IWYU mapping file |
| 141 | [ |
| 142 | # Map internal LLVM headers to public ones |
| 143 | { "include": ["<llvm/ADT/StringRef.h>", "private", |
| 144 | "<llvm/ADT/StringRef.h>", "public"] }, |
| 145 | |
| 146 | # Map system headers to POSIX equivalents |
| 147 | { "include": ["<bits/types.h>", "private", "<sys/types.h>", "public"] }, |
| 148 | { "include": ["<bits/socket.h>", "private", "<sys/socket.h>", "public"] }, |
| 149 | |
| 150 | # Symbol → header mappings |
| 151 | { "symbol": ["std::s |