摘要:使用include-what-you-use(iwyu/IWYU)清理冗余头文件,补充必要头文件。

本文分享自华为云社区《用include what you use拯救混乱的头文件》,作者: 村头树下 。

背景

面对大型C/C++项目的时候,混乱的头文件引用,经常会有一种剪不断理还乱的感觉。长年累月的项目迭代,需求更新。导致头文件未能及时随着代码的变动而更新,成为了冗余的负担。这会增加整体项目的编译时间。如果没有一个工具来帮助我整理这些头文件,我是绝对不会动一丝整改他们的想法。幸运的是,有一个工具可以满足我们的要求–include what you use.

简介

在各种C/C++编码规范中,一般都会提到几点:

禁止包含用不到的头文件

用不到的头文件被包含的同时,引入了不必要的依赖,增加了模块之间的耦合度,只要该头文件修改,代码就会重新编译。

头文件应该自包含

如果一个文件包含某个头文件。想要正常工作,还必须包含另外一个头文件,这会增加使用的负担。

所以这也是整理头文件的意义。
这也是使用include-what-you-use(下称IWYU)的初衷。

安装

附上此项目的主页
https://github.com/include-what-you-use/include-what-you-use
IWYU依赖Clang,而且它针对Clang的各个版本都有自己对应的版本。所以在安装IWYU的时候,首先需确定你的Clang是什么版本。由于本人之前未曾安装过Clang,所以首先要安装Clang.

Clang的安装

建议直接源码编译,减少符号不兼容等奇怪的错误
克隆llvm仓库

git clone https://github.com/llvm/llvm-project.git

切到想要编译的llvm版本

cd llvm-project
git checkout llvmorg-14.0.0

构建LLVM和Clang

cd llvm-project
mkdir build && cd build
cmake -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_BUILD_TYPE=Release -G “Unix Makefiles” …/llvm
make -j48

IWYU安装

克隆IWYU仓库

git clone https://github.com/include-what-you-use/include-what-you-use.git
cd include-what-you-use

切换到与clang对应的分支,由于刚才安装的是14.0的版本,因此这里也切换到对应版本

git checkeout clang_14

在IWYU上一层创建文件夹build

mkdir build && cd build
cmake -G “Unix Makefiles” -DCMAKE_PREFIX_PATH=…/llvm/llvm-project/llvm/ …/include-what-you-use/

CMAKE_PREFIX_PATH指向刚才构建的llvm目录。如果构建成功,你会看到

开始编译IWYU

cd …/include-what-you-use/
make -j48

编译成功

如果希望更方便的使用iwyu,可以将其bin加入环境变量中,我是创建了一个软链接到/usr/bin目录下

ln -s /the/path/of/include-what-you-use/bin/include-what-you-use /usr/bin/iwyu

如果一切妥当,就可以用iwyu -v来检查是否安装成功了

使用

这里介绍一下在Clion环境下,如何使用IWYU
打开Clion->File->Setting->Build,Execution,Deployment页面

  • 设置编译器
    在官方文档中,介绍使用IWYU的时候,使用Clang作为编译器。通过亲自实践发现,在14.0版本下,Gcc 7.3.1也是可以使用IWYU的。
    在Toolchains中设置Clang的路径,由于我Gcc也可以运行,所以并没有更改

  • 设置编译选项
    ->Cmake设置页面。
    新建一个编译模板名为Debug-iwyu,重点是在Cmake options中添加 -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=iwyux 其中iwyu为你环境中实际include-what-you-use可执行文件的路径

  • 编译项目
    在编译项目的界面选择刚刚创建的编译模板Debug-iwyu

    OK,一切准备就绪,就可以开始编译了。

  • 结果处理
    这里举了一个很简单的例子,main.cpp包含了三个用不到的头文件

    然后iwyu在编译的过程中会提醒我们这三个头文件应该被移除

    但是真实的大型项目中,肯定会有很多的提醒,一个一个去手动修改。依然是个机械的苦力活,所以在iwyu项目中,提供了一个可以辅助自动修复的脚本fix_includes.py。可以参照项目主页的使用方法,来帮助自动修复。

点击关注,第一时间了解华为云新鲜技术~

整理混乱的头文件,我用include what you use的更多相关文章

  1. c++ 头文件包含问题-include&class

    http://blog.csdn.net/jiajia4336/article/details/8996254 前向声明概念(forward declaration) 在程序中引入了类类型的B.在声明 ...

  2. Object-c 语法 - 头文件引用(@class/#import/#include)

    一. Objective-C 中 #import 和 #include 的区别 预编译指令 Objective-C:#import:由gcc编译器支持 C,C++:#include 在 Objecti ...

  3. c语言头文件中定义全局变量的问题

    c语言头文件中定义全局变量的问题 (转http://www.cnblogs.com/Sorean/) 先说一下,全局变量只能定义在 函数里面,任意函数,其他函数在使用的时候用extern声明.千万不要 ...

  4. C/C++关于string.h头文件和string类

    学习C语言时,用字符串的函数例如stpcpy().strcat().strcmp()等,要包含头文件string.h 学习C++后,C++有字符串的标准类string,string类也有很多方法,用s ...

  5. cocos2dx中使用声音引擎需要包含的头文件

    1.需要包含的头文件和命名空间 #include "SimpleAudioEngine.h"using namespace CocosDenshion;

  6. C/C++常用头文件及函数汇总

    转自: C/C++常用头文件及函数汇总 C/C++头文件一览 C #include <assert.h> //设定插入点#include <ctype.h> //字符处理#in ...

  7. linux常用头文件及说明

    linux常用头文件及说明 1. Linux中一些头文件的作用: <assert.h>:ANSI C.提供断言,assert(表达式)<glib.h>:GCC.GTK,GNOM ...

  8. c语言头文件和源文件不在同一个目录

    http://www.cnblogs.com/ShaneZhang/archive/2013/05/20/3088688.html 从工程上讲,头文件的文件名应该与对应的源文件名相同便于维护,如果头文 ...

  9. 正确使用c语言中的头文件

    我们在使用c编程的时候经常会遇到头文件,前段时间我自己做了个小项目的时候,也遇到了关于头文件的问题. 预处理器发现#include 指令后,就会寻找后跟的文件名并把这个文件包含的内容包含到当前文件中. ...

  10. sort()函数与qsort()函数及其头文件

    sort()函数与qsort()函数及其头文件 sort()函数是C++中的排序函数其头文件为:#include<algorithm>头文件: qsort()是C中的排序函数,其头文件为: ...

随机推荐

  1. 关于长链剖分的数组实现 | CF1009F Dominant Indices

    请容许我不理解一下为什么这题题解几乎全都是指针实现/kk 其实长链剖分是可以直接用数组来写的. 考虑朴素 DP.设 \(f_{u,i}\) 表示以点 \(u\) 为根的子树中与点 \(u\) 距离为 ...

  2. WC 2023 冬眠记

    打得很烂,果然还是太菜了. Day -? 连第二课堂都听不懂,我选择冬眠. Day 1 发压缩包时看大小猜测今年又有交互题.果不其然. 那就只剩下两道可做题了(悲) 通读题面,尝试思考 T1,无果,周 ...

  3. CF48C [The Race]

    Problem 题目简述 现有 \(n\) 个已经加过油的加油站,如果当前剩余油量 \(< 10\) 升,则会加 \(x\) 升的油. 初始状态下,有 \(x\) 升油.每个加油站之间的距离为 ...

  4. 深入理解JMeter中的JSON Extractor

    Apache JMeter是一款出色的开源性能和功能测试工具,这款工具提供了丰富的功能和强大的扩展性,可以应对各种复杂的测试需求.当我们在进行接口测试时,经常会遇到需要从接口响应中提取信息并在后续请求 ...

  5. 在 Windows 系统上运行 VIC 水文模型

    目录 配置 WSL2 和 Ubuntu 系统 启用 WSL2 安装 Linux 发行版 配置 Ubuntu 安装 VIC 并测试 Stehekin 数据集 VIC 模型安装 samples 测试 VI ...

  6. 【javaweb】integer是什么意思?integer和int的区别

    1.数据类型不同:int是基础数据类型,而integer是包装数据类型 2.默认值不同:int的默认值是0,而integer的默认值是null 3.内存中存储的方式不同:int 在内存中直接存储的是数 ...

  7. 【Servlet】两种配置

    web.xml中Servlet的注解 <servlet> <!-- servlet的内部名称,⾃定义 --> <servlet-name>类名</servle ...

  8. .NET周刊【11月第4期 2023-11-26】

    国内文章 万字长文:从 C# 入门学会 RabbitMQ 消息队列编程 https://www.cnblogs.com/whuanle/p/17837034.html 如题,详细的介绍RabbitMQ ...

  9. Eclipse 安装 ABAP 插件报错 Microsoft Visual C++ 2013 (x64) 快速解决

    去官网下载Microsoft Visual C++ 2013 (x64) 安装   Download Visual C++ Redistributable Packages for Visual St ...

  10. Grid 拖拽布局实现

    最近有个需求需要实现自定义首页布局,需要将屏幕按照 6 列 4 行进行等分成多个格子,然后将组件可拖拽对应格子进行渲染展示. 示例 对比一些已有的插件,发现想要实现产品的交互效果,没有现成可用的.本身 ...