1. 程式人生 > >是否有去除c++多餘標頭檔案的工具

是否有去除c++多餘標頭檔案的工具

2016-03-10

工具已經上傳到 GitHub - cxxclean/cxx-clean-include

目前支援對visual studio單個c++專案作清理,以及清理整個資料夾下的c++檔案

舉個例子,比如現在有visual studio 2005專案hello.vcproj,那麼使用命令:

cxxclean -clean hello.vcproj --

將會清理專案內的cpp檔案以及cpp檔案所#include到的標頭檔案

再比如有一個資料夾hello,那麼使用

cxxclean -clean ./hello/ --

將清理hello資料夾下的cpp檔案以及cpp檔案所#include到的標頭檔案

github頁面上我上傳了hello.sln工程,在嘗試使用本工具清理自己的專案之前,可以先在hello.vcxproj專案作測試

另外,清理c++專案前請務必使用版本工具備份!

其餘的看github說明

--------------

2016-04-20

我是提問者,上面是我之前在3月10號的回答,由於當時工具初步完成(沒錯,我提問的時候其實工具壓根還沒寫好),自己本身也較忙,所以回答並不詳細,現在一個多月過去了,工具已經完善,文件、程式碼註釋、說明檔案也都已經補齊。我覺得應該再補充說明一下,同時,各答主們推薦的工具作說明我也試用了一些,試用情況我也會稍作說明,以方便有需要的人選擇合適的工具。

這裡要說的一點是,如果你的專案編譯比較久,在使用各答主們推薦的工具之前,最好先試一下預編譯、聯合編譯、ccache之類的快取工具這3種方法,因為這3種方法對編譯速度的提升是非常巨大的,僅當你在採用後仍然對編譯時間不滿意,且沒有充足的時間和精力和金錢來解決,才有必要考慮清理c++檔案內多餘的#include。

首先是
@chys
答主提到的include-what-you-use工具,該工具目前可以在windows和Ubuntu下直接使用,其他平臺上則需要再下載llvm+clang進行編譯(編譯時間會很長,應該在1個小時左右),根據我的試用和猜測,include-what-you應該是本問題的各回答中處理單個cpp檔案時功能最強大的一個工具,支援刪除無用的#include,支援自動用前置宣告替換掉#include語句,支援在#include語句後添加註釋,但個人認為上手較為困難,需要安裝python環境,而且在windows下較難自動化處理,引數使用困難,而且很遺憾的是,include-what-you-use似乎每次都只單獨對一個cpp進行分析,這也意味著它只能採用最保守的只清理cpp不清理h檔案的方式來保證清理完後不會產生一堆編譯錯誤。推薦在linux系統下采用該工具。

還有匿名答主提到vs外掛Resharper For C++,這個外掛很易用而且提示效果友好,當你用vs開發某個cpp檔案時,用這個外掛可以點一下就清理掉cpp檔案內多餘的#include,而且如果某行#include無效,#include整行會自動變灰暗,看上去非常直觀,因此推薦用vs的朋友使用該外掛來清理單個的cpp檔案。缺點也很明顯,如果想要清理大批量的cpp檔案會點到手痠,並且只清理當前檔案,無法清理當前檔案包含的其他檔案內的#include,也不支援include-what-you-use可以做到的自動替換前置宣告。推測其是根據單詞匹配來清理的。

還有
@陳曉輝
提到的deheader工具,採用python開發,因此也需要python環境,看了下原始碼,原理應該也是基本的單詞匹配。所能達到的效果估計和Resharper For C++較為類似。

此外還有 @jiangcy 提到的clion這款ide以及 @韓葆-逸鬆 提到的Coverity,由於沒有合適的環境試用所以不清楚實際效果,希望有了解的知友能告知一下。

最後就是我開發的工具了,現在的名字叫cxx-clean-include,目前僅提供win32可執行檔案(linux下也能編譯),是基於llvm+clang開發的,可以做到清除無用#include、用前置宣告替換#include、儘量用深層#include替換淺層#include,同時該工具額外的一個效果是:如果只給1個cpp,可以把cpp包含的其他標頭檔案一起清理(位於專案資料夾下的標頭檔案才會被清理),如果給多個cpp,則會先把這些cpp檔案的分析結果彙總起來再逐一清理。比如,假設2個cpp檔案都包含標頭檔案a,分析第1個cpp檔案時認為標頭檔案a的第1行#include沒用,分析第2個cpp檔案時卻認為標頭檔案a的第1行#include有用,最終結果就是,標頭檔案a的第一行#include不應被刪除。

具體本工具達到的效果在上面3月10號的回答裡已經講了,下面要講講是本工具的原理,這樣大家在使用的時候可以有個整體的概念,也希望對有興趣的人有所幫助。


cxx-clean-include的簡要原理如下(此外還有很多細節未一一說明,但下面已經涵蓋了對單個檔案的基本分析流程):

1. 清除多餘的#include(這一步最簡單)

以下圖為例

<img src="https://pic2.zhimg.com/2c424aa443a9eeadb8f1c9b2b8177a49_b.jpg" data-rawwidth="820" data-rawheight="529" class="origin_image zh-lightbox-thumb" width="820" data-original="https://pic2.zhimg.com/2c424aa443a9eeadb8f1c9b2b8177a49_r.jpg">

上圖表示,雖然[主檔案.cpp]包含了很多檔案,但只用到了B2.h、D2.h、E1.h標頭檔案

處理辦法:保留有用檔案的所有祖先檔案

處理的結果如下圖

https://www.zhihu.com/question/39796313?sort=created