Include-what-you-use工具介紹


簡介

Include-what-you-use工具(以下簡稱iwyu)是Google推出,基於Clang的C/C++工程冗余頭文件檢查工具。iwyu依賴Clang編譯套件,因此,針對每個Clang版本,會有對應的iwyu工程分支。

使用該工具的好處

  • 更快的編譯。當cpp文件包含冗余頭文件時,編譯器會讀取、預處理和解析更多的代碼,如果有模板存在,則會引入更多的代碼,這會加大編譯構建時間。
  • 更好的重構。假如你准備重構foo.h,使得它不再使用vector,你很可能會從foo.h文件中移除#include<vector>。理論上可以這么做,但實際上不行,因為其他文件可能會通過foo.h來間接引用vector,貿然移除會造成其他文件編譯失敗。iwyu工具可以找到並去掉這種間接引用。
  • 頭文件自注釋。通過查看必須頭文件注釋,可知道該功能依賴於其他哪些子功能。
  • 使用前向聲明代替include語句,減少依賴,減少可執行程序大小

Windows平台下使用

Window平台上,使用如下版本:

  • clang_8.0
  • iwyu 0.12
  • Visual Studio 2017

使用預編譯LLVM來構建

下載並安裝LLVM-8.0.0二進制安裝包,安裝在D:\Program Files\LLVM下,使用如下語句來構建:

cd iwyu/build
cmake -G "Visual Studio 15 2017" Win64 -DCMAKE_PREFIX_PATH=D:\Program Files\LLVM ../include-what-you-use/

提示如下錯誤:

使用預編譯發布包來構建iwyu.png

由於二進制安裝包不包含iwyu構建cmake所需的查找文件LLVMConfig.cmake,導致構建失敗,不采用這種方式來構建。

參考鏈接:Embeding LLVM in your project

備注:后來發現,通過編譯llvm源碼,可以從源碼中的LLVMConfig.cmake.in生成對應的LLVMConfig.cmake文件,那這樣還不如直接使用源碼來構建。

使用源碼來構建

下載iwyu 0.12版本,此版本依賴clang_8.0版本,在llvm官網上,下載LLVM 8.0.0版本的LLVMClang源碼。按照如下順序來存放:

  1. 新建llvm目錄以及同級別的llvm-build目錄
  2. llvm_8.0源碼解壓到llvm目錄中
  3. llvm/tools/目錄下新建clang目錄,將clang源碼在此目錄解壓
  4. iwyu 0.12源碼復制到llvm/tools/clang/tools/目錄
  5. 編輯llvm/tools/clang/tools/CMakeLists.txt,增加以下一句話

    add_clang_subdirectory(include-what-you-use-clang_8.0)

最后形成的目錄結構如下:

llvm-build
llvm
 -- tools
 ---- clang
 ------tools
 --------include-what-you-use-clang_8.0
 

源碼目錄結構准備好,通過cmake-gui來進行配置。

cmake-gui配置iwyu.png

備注:在構建時,要選擇Win64版本,如果選擇Win32來構建,會出現fatal error C1060: 編譯器的堆空間不足的問題,經過查找資料,是32位cl.exe編譯器使用超過3.5G內存時會報錯。

構建完成后,進行如下調整:

  1. 去掉所有的打勾,只保留以下四項打勾:
  • LLVM_ENABLE_IDE
  • LLVM_INCLUDE_TOOLS
  • LLVM_INCLUDE_UTILS
  • LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD
  1. 將LLVM_DYLIB_COMPONENTS由all改為host、將LLVM_TARGETS_TO_BUILD由all改為host。減少構建工程輸出

配置完成后重新生成和構建,打開LLVM.sln工程,直接生成include-what-you-use工程,缺少哪些庫,就編譯哪些庫。

構建結果如下:
windows上編譯結果.png

由於該工具基於clang,因此,在使用時有兩部分選項:

  • iwyu選項,需要添加-Xiwyu前綴來明確指出
  • clang選項。例如,如果需要支持c++11,需要添加
    • -x c++ 表示編譯的是c++類型文件
    • -std=c++11 表示按c++11規范來編譯

備注:使用clang的c++11標准來編譯,在使用auto關鍵字時,會提示

error: 'auto' return without trailing return type; deduced return types are a C++14 extension

相關問題鏈接在此。clang建議使用c++14類型,或者使用 -> decltype 來聲明返回類型。

如果不明確指出,可以忽略clang的選項。

使用方法如下:

.\include-what-you-use.exe -Xiwyu -transitive_includes_only XXX.cpp

Linux平台下使用

在Linux平台下的構建流程簡單直接。

  1. 安裝clang,查看Clang的版本
    buntu_clang_version.png
    當前系統使用的Clang版本為3.8.
  2. 新建iwyu目錄,下載對應Clang版本的iwyu源碼,
    git clone -b clang_3.8 https://github.com/include-what-you-use/include-what-you-use.git
    • iwyu依賴curses庫,如果沒有安裝,需要執行sudo apt-get install libncurses5-dev來安裝
    • iwyu依賴Clang開發包,如果只是通過apt命令行安裝Clang,需要使用
      sudo apt-get install libclang-3.8-dev來安裝開發包
  3. 使用cmake源碼外來構建iwyu工具
  • mkdir build && cd build
  • cmake -G "Unix Makefiles" -DIWYU_LLVM_ROOT_PATH=/usr/lib/llvm-3.8 ../include-what-you-use
  • make
  • make install
    構建過程中,出現如下錯誤:
    編譯iwyu時出錯_無法找到Declbase_h.png
    經分析發現時本機未安裝Clang開發包,參照上面提到的來安裝即可。
    構建完成后,在當前目錄下生成 include-what-you-use 工具,后續使用它即可。

測試

以一個簡單c++程序來測試:使用./include-what-you-use simple_test.cpp來進行靜態分析,如果使用了C++11特性,則需要添加-std=c++11


#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/user.h>
#include <execinfo.h>

int main(int argc, char* argv[])
{
    return 0;
}

分析結果如下:

include-what-you-use分析結果.png

根據上述結果即可進行有針對性的頭文件包含優化。

工程整合

使用cmake構建工具,直接支持iwyu工具,配合iwyu源碼下的fix_includes.py腳本工具,可進行自動化清理。

CMake 3.3版本引入目標新屬性CXX_INCLUDE_WHAT_YOU_USE,支持iwyu工具。

使用方法如下:

cmake .. -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=$(which include-what-you-use)
make 2> iwyu.out
fix_includes.py -n --nosafe_headers --comments < iwyu.ou # 該命令輸出准備刪除的動作,去掉-n選項,會修改實際源文件。  --comments:在每個include中指出具體使用了哪些導出函數

可依據iwyu.out內容來手動移除,也可使用fix_includes.py來進行自動化清理。

參考文檔:

  1. C++中include-what-you-use(iwyu)去除多余頭文件工具開發文檔

  2. 使用 include-what-you-use 檢測冗余頭文件

  3. Include-What-you-use的GitHub主頁

  4. Include What You Use

  5. 源碼以及編譯好的二進制文件下載鏈接: https://pan.baidu.com/s/1lf3BP4E_OSMtkSnZRezRIw 提取碼: wvs5


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM