关于 include-what-you-use
include-what-you-use 为使用 IWYU 管理 C 和 C++ 头文件引用的 Agent 提供指导,涵盖报告解读、自动修复、前向声明、映射文件及 CMake 集成。
主要功能
- 01对源文件或构建运行 IWYU
- 02解读头文件增删建议
- 03用 fix_include 应用修复
- 04选择前向声明或完整头文件
- 05配置映射文件和 CMake
适用场景
- 01移除未使用的头文件引用
- 02查找缺失的直接依赖
- 03减少编译级联
- 04将头文件检查集成到 CMake 构建
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mohitmishra786/ low-level-dev-skills --skill include-what-you-use安装后在 Claude Code 中输入/include-what-you-use确认已加载。
详细介绍
按需包含(IWYU)
用途
指导 Agent 使用 IWYU 减少不必要的 #include 指令、解读 IWYU 报告和映射文件、决定使用前向声明还是完整包含,以及将 IWYU 集成到 CMake 构建中,从而减少大型代码库中的编译级联。
触发条件
- “如何使用 include-what-you-use?”
- “如何通过修正包含项缩短 C++ 编译时间?”
- “如何解读 IWYU 输出?”
- “应该使用前向声明还是包含头文件?”
- “如何将 IWYU 集成到 CMake 中?”
- “什么是编译级联,如何避免?”
工作流
1. 安装并运行 IWYU
# Install
apt-get install iwyu # Ubuntu/Debian
brew install include-what-you-use # macOS
# Run on a single file
iwyu -Xiwyu --error main.cpp 2>&1
# Run via compile_commands.json
iwyu_tool.py -p build/ src/main.cpp 2>&1 | tee iwyu.log
# Run on entire project
iwyu_tool.py -p build/ 2>&1 | tee iwyu.log
2. CMake 集成
# CMakeLists.txt — use IWYU as include checker during build
find_program(IWYU_PROGRAM NAMES include-what-you-use iwyu)
if(IWYU_PROGRAM)
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE
${IWYU_PROGRAM}
-Xiwyu --mapping_file=${CMAKE_SOURCE_DIR}/iwyu.imp
-Xiwyu --no_comments
)
endif()
# Build with IWYU analysis
cmake -S . -B build -DCMAKE_CXX_COMPILER=clang++
cmake --build build 2>&1 | tee iwyu.log
3. 解读 IWYU 输出
main.cpp should add these lines:
#include <string> // for std::string
#include "mylib/widget.h" // for Widget
main.cpp should remove these lines:
- #include <vector> // lines 5-5
- #include "internal/detail.h" // lines 8-8
The full include-list for main.cpp:
#include <iostream> // for std::cout
#include <string> // for std::string
#include "mylib/widget.h" // for Widget
---
阅读输出:
- should add:提供了已使用符号、但尚未包含的头文件
- should remove:已包含但其符号未被直接使用的头文件
- The full include-list:最终头文件列表应呈现的形式
4. 自动应用 IWYU 修复
# fix_include script (comes with IWYU)
fix_include < iwyu.log
# Options
fix_include --nosafe_headers < iwyu.log # more aggressive — also removes system headers
fix_include --comments < iwyu.log # preserve // comments in includes
fix_include --dry_run < iwyu.log # preview changes without applying
# Limit to specific files
fix_include --only_re='src/.*\.cpp' < iwyu.log
# Run and apply in one pipeline
iwyu_tool.py -p build/ 2>&1 | fix_include
5. 前向声明与完整包含
当不需要完整类型时,IWYU 倾向于使用前向声明(不带定义的类/结构体声明):
// full_include.h — DON'T include this if only a pointer is used
#include "widget.h" // full definition: Widget members, vtable, etc.
// forward_decl.h — OK when Widget* or Widget& is sufficient
class Widget; // forward declaration
void process(Widget *w); // pointer: forward decl is enough
// When forward declaration is sufficient:
// - Pointer or reference parameter: Widget*, Widget&
// - Return type as pointer: Widget*
// - Base class declared elsewhere (but defined in .cpp)
// When full include is required:
// - Inheriting from Widget: class MyWidget : public Widget
// - Accessing Widget members: w.field, w.method()
// - Creating Widget instances: Widget w;
// - Sizeof(Widget)
// - Template instantiation: std::vector<Widget>
// IWYU-friendly header
#pragma once
class Widget; // forward declare (saves downstream compilation)
class Container {
Widget *head_; // pointer: forward decl is enough
public:
void add(Widget *w);
Widget *get(int idx);
};
// Container.cpp includes "widget.h" — only .cpp pays the compile cost
6. 第三方头文件的映射文件
IWYU 映射文件会告知 IWYU 间接包含关系(例如,某个内部 STL 头文件提供了 #include <vector>):
# iwyu.imp — IWYU mapping file
[
# Map internal LLVM headers to public ones
{ "include": ["<llvm/ADT/StringRef.h>", "private",
"<llvm/ADT/StringRef.h>", "public"] },
# Map system headers to POSIX equivalents
{ "include": ["<bits/types.h>", "private", "<sys/types.h>", "public"] },
{ "include": ["<bits/socket.h>", "private", "<sys/socket.h>", "public"] },
# Symbol → header mappings
{ "symbol": ["std::string", "private", "<string>", "public"] },
{ "symbol": ["NULL", "private", "<cstddef>", "public"] },
]
# Use mapping file
iwyu -Xiwyu --mapping_file=iwyu.imp main.cpp
# IWYU ships with common mappings
ls /usr/share/include-what-you-use/
# gcc.stl.headers.imp, boost-1.62.imp, libcxx.imp, etc.
iwyu -Xiwyu --mapping_file=/usr/share/include-what-you-use/gcc.stl.headers.imp
7. IWYU 不会做什么
IWYU 有其局限,请注意:
# IWYU may give wrong advice for:
# - Macros from headers (hard to track)
# - Template specializations in included headers
# - Headers required for correct ODR linking
# Safe iterative workflow:
# 1. Run IWYU
# 2. Apply fixes with fix_include
# 3. Rebuild and run tests
# 4. Revert any changes that break the build
# 5. Repeat until clean
# Check for compilation cascade: how many TUs include a header
grep -rl '#include "expensive.h"' src/ | wc -l
相关技能
- 使用
skills/build-systems/build-acceleration了解 ccache 和其他编译加速技巧 - 使用
skills/build-systems/cmake了解如何将构建分析工具集成到 CMake 中 - 使用
skills/compilers/cpp-modules了解如何将 C++20 模块作为长期解决方案,减少包含膨胀
评论
支持 Markdown