1. 程式人生 > >C++中include-what-you-use(iwyu)去除多餘標頭檔案工具開發文件

C++中include-what-you-use(iwyu)去除多餘標頭檔案工具開發文件

開篇敬知乎大神~
大神首頁

作業系統: Windows

所需工具: SVN、CMake、visual studio 2015以上版本、Sublime Text 3

操作步驟:

1.新建llvm資料夾,使用svn將llvm官方原始碼匯出到該資料夾

2.在llvm/tools下新建clang資料夾,使用svn將clang官方原始碼匯出到該資料夾

3.到此,已準備好了所需的原始碼,開始使用CMake生成專案檔案

      3.1新建llvm-build資料夾(不能在llvm資料夾底下),用於存放CMake生成的專案檔案




      3.2 [可選]為了減少CMake匯出量,可作以下配置(以cmake-gui為例)




                         a. CMake裡先將所有的打勾都取消


                         b.將所有的all改成host,意思是隻針對本平臺進行配置


                         c.給下面的選項打勾


                           LLVM_INCLUDE_TOOLS


                           LLVM_INCLUDE_UTILS

                           LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD本項含義是:
                           編譯llvm\tools\clang\tools\extra下的專案


                         d.將所有的MD換為MT,將MDd換為MTd




      3.3使用CMake匯出vs專案檔案
       PS:Cmake這個專案不是必需的,但的確可以大大方便生成專案檔案,我遇到了一個問題就是Cmake不好用
        我的方法是:使用cmd命令列來生成專案檔案,在命令列輸入:
        C:\project\llvm-build>cmake–G ”Visual Studio 15 2017” ../llvm –Thost=x64

4.使用VS開啟llvm-build/llvm.sln,選中clang專案然後生成(約1小時)。

5.將iwyu專案新增到clang專案中,一般是複製到llvm\tools\clang\tools資料夾下,這個要看iwyu的文件

6.使用Sublime Text 3編輯llvm/tools/clang/tools/CMakeLists.txt,在裡面新增

add_subdirectory(include-what-you-use)

7.使用Cmake重新生成專案檔案。

8.在VS中提示發生更改,重新載入一下即可。

9.在VS中生成include-what-you-use

PS:生成的時候遇見了兩個小警告(TemplateSpecializationType::PrintTemplateArgumentList和TemplateSpecializationType:: TemplateArgumentListInfo),應該和列印引數有關,註釋掉就OK了。

專案測試:

例項1:

建立

        a.h
        b.h
        c.h
        ttt.cpp

在命令列輸入命令:

C:\project\llvm-build\bin\Debug\include-what-you-use.exe-x c++ -std=c++11 -Xiwyu –verbose=2 -Xiwyu –transitive_includes_only ttt.cpp2> iwyu.out

輸出的結果將被重定向到iwyu.out檔案中
輸出結果

例項2:

建立foo.cpp檔案
在命令列輸入命令:

C:\project\llvm-build\bin\Debug\include-what-you-use.exe-x c++ -std=c++11 -Xiwyu –verbose=2 -Xiwyu –transitive_includes_only foo.cpp2> iwyu.out

輸出的結果將被重定向到iwyu.out檔案中
輸出結果

其實,在網路中查詢此開發工具過程中,發現iwyu更適合在Linux系統工作,Windows系統大大增加了編譯的難度,include-what-you-use(等下直接簡稱為iwyu)的確是一個很有用的工具,可以自動刪除不必要的#include並能生成前置宣告,雖然較難上手,但一旦建立起自動化處理機制後,可以很方便的清理專案的c++檔案中多餘的#include。
但iwyu的主要不足是:去除標頭檔案中多餘的#include不夠徹底,或者說,可以很徹底,但大部分情況下將會導致其他的檔案發生編譯錯誤。

通過跟蹤其原始碼實現流程以及結合使用的情況來看,iwyu對於c++檔案的清理僅依賴於通過單個檔案的解析,並沒能分析出整個專案的依賴圖。這也決定了iwyu的主要使用場景是清理.cpp檔案,而非.h檔案,因為這樣更安全。
舉一個例子:
假設有all.h,裡面有包含2個有用的標頭檔案,3個沒用的標頭檔案
all.h包括#include “a.h”#include “b.h” #include “永遠用不到的標頭檔案1.h” #include “永遠用不到的標頭檔案2.h”#include “永遠用不到的標頭檔案3.h”class C{};

現在,假設專案中的A.cpp和B.cpp均包含了all.h,其中,A.cpp僅使用了"a.h"內的內容,而B.cpp僅使用了"b.h"的內容。
此時使用iwyu處理A.cpp和B.cpp,A.cpp中的#include"all.h"將被替換為#include "a.h",B.cpp中的將被替換為#include "b.h",而all.h內容並不會改動。
但我們還是希望all.h中多餘的3個檔案能被清理掉的,於是我們繼續使用iwyu清理all.h,但很明顯iwyu是不知道a.h和b.h是曾經被使用到的,於是all.h最後將變成

all.h
class C{};
all.h中所有的#include,包括#include”a.h”和#include “b.h”都被刪掉了,於是專案將發生編譯錯誤。
這個問題挺難避免的,比較折中的做法是隻清理cpp檔案,再根據需求自行清理h檔案。但相應的清理效果就可能會大打折扣了。因為說不定就是某些無用的h檔案被大量cpp檔案包含才導致專案編譯速度變慢的,而我們又不方便直接定位到這些#include。
所以生成專案中的各個檔案的依賴關係結構是很有必要的,iwyu在這方面仍然不足,所以我覺得還是可以把工具發出來作為備用。
而對於linux下的c++專案,由於iwyu已經做得足夠強大,Windows系統大大增加了編譯的難度。