mcpField
I
include-what-you-use

include-what-you-use

github.com/mohitmishra786开发269495 次安装18 周前更新
代码仓库

关于 include-what-you-use

include-what-you-use 为使用 IWYU 管理 C 和 C++ 头文件引用的 Agent 提供指导,涵盖报告解读、自动修复、前向声明、映射文件及 CMake 集成。

主要功能

  1. 01对源文件或构建运行 IWYU
  2. 02解读头文件增删建议
  3. 03用 fix_include 应用修复
  4. 04选择前向声明或完整头文件
  5. 05配置映射文件和 CMake

适用场景

  1. 01移除未使用的头文件引用
  2. 02查找缺失的直接依赖
  3. 03减少编译级联
  4. 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