cmake構建C++項目避免編譯時對第三方庫頭文件進行依賴檢查

最近有同事反應一個使用cmake構建的C++項目編譯很慢,具體表現是隨便修改一個很簡單的cpp源文件後,從新編譯生成可執行文件的時間須要用3分鐘左右。統計了一下整個增量編譯過程各階段耗時,發現時間主要消耗在了cmake生成依賴規則和make檢查依賴規則上。生成的依賴規則文件depend.make有200M左右,包含依賴規則條目有100W行以上。因此生成依賴規則和檢查依賴都會消耗大量時間。進一步分析,查看這些依賴規則90%以上都是對三方庫頭文件的依賴。這些依賴顯然是沒必要要的,由於三方庫頭文件是不可能輕易被修改的。那麼如何消除這些沒必要要的依賴呢?
哪一個搜索引擎也沒有幫我找到滿意的答案,不得已只能從cmake源碼入手。因爲項目使用cmake版本爲3.5.1,因此一開始從3.5.1版本cmake源碼入手。發現cmake使用cmLocalGenerator::GetIncludeDirectories接口得到當前target所包含的路徑,這個接口主要有兩處調用:一處用來生成flags.make中的CXX_INCLUDES編譯參數;另外一處用來生成DependInfo.cmake中的CMAKE_CXX_TARGET_INCLUDE_PATH參數,而編譯規則文件就是根據這個參數生成的。不幸的是,兩處調用對從該接口得到的頭文件目錄列表都沒有作任何處理,也就是說編譯參數中指定的頭文件目錄和依賴檢查目錄必定是徹底相同的。若是使用必定的手段(如CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES選項)去除了依賴檢查目錄中的某個目錄,也必定會致使在編譯參數中該目錄被去除,這樣就通不過編譯了。雖然這條路被堵死了,但仍是有一些可作的工做,那就是在cmake讀取DependInfo.cmake文件生成depend.make時作些手腳,在這個帖子有提到用include_regular_expression("^([^b]|b[^o]|bo[^o]|boo[^s]|boos[^t]|boost[^/]).*$") 在生成依賴規則時過濾掉對boost的依賴,可是顯然侷限性很大,由於包含boost頭文件時都會加上boost目錄名,因此很容易過濾,但並非全部三方庫都是這樣的。
就在我計劃着寫一個超長的正則表達式時,我又打開了查看了另外一個項目的代碼,這個項目編譯速度不錯。驚奇的發現這個項目的某一個target的flags.make和DependInfo.cmake中的頭文件目錄居然不一樣,因此又編譯了一份最新的3.12.4的cmake進行調試查看源碼,果不其然,在這個版本中,生成DependInfo.cmake中頭文件目錄的代碼變成了這樣:正則表達式

     this->GetIncludeDirectories(includes, target, implicitLang.first, config);
     std::string binaryDir = this->GetState()->GetBinaryDirectory();
     if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) {
       const char* sourceDir = this->GetState()->GetSourceDirectory();
       cmEraseIf(includes, ::NotInProjectDir(sourceDir, binaryDir));
     }
     for (std::string const& include : includes) {
       cmakefileStream << "  \""
                       << this->MaybeConvertToRelativePath(binaryDir, include)
                       << "\"\n";
     }
     cmakefileStream << "  )\n";
1
2
3
4
5
6
7
8
9
10
11
12
它使用了CMAKE_DEPENDS_IN_PROJECT_ONLY這個選項對依賴檢查目錄進行了過濾,若是這個選項被打開,依賴檢查目錄列表就會忽略外部的第三方庫頭文件,這樣就不會致使產生一個超大的depend.make文件了。
因此直接set(CMAKE_DEPENDS_IN_PROJECT_ONLY ON)應該是解決這個編譯慢問題的最快捷方法了。然而不幸的是這個選項是在cmake 3.6.0版本才引入的,當前環境的3.5.1版本cmake用不了,我也沒權限升級軟件,因此最後仍是寫了一個超長的正則表達式,效果也還行。
--------------------- 
做者:imred 
來源:CSDN 
原文:https://blog.csdn.net/imred/article/details/83759223 
版權聲明:本文爲博主原創文章,轉載請附上博文連接!express

相關文章
相關標籤/搜索