bazel學習總結(一)

最近工作需要,開始學習bazel自動化構建工具,上網搜了搜並沒有一個很系統的講解文檔,只有google的官方文檔可以閱讀,然而官方文檔的組織多而雜亂,且不成體系,給入門造成了不小的困難,故準備憑我如今兩週看了三遍文檔的膚淺學習,系統的寫一下這個系列的博客,供後人參考,也再讓我自己整理一遍這些知識。

一、bazel是用來幹啥的

bazel簡單來說就是用來自動化構建大型工程的,和make, maven之類的工具屬於一類東西,他的目標是當項目裏的一部分程序修改後,只需要幾個命令就可以將整個項目進行重新編譯,且要求快。它還可以進行自動化測試,當然這些都必須由你來編寫測試流程和規則。因爲我們項目用的c++,而且bazel對c++的支持很完善,所以我的整個系列都只針對c++來說。

二、bazel的文件管理架構

bazel中對於文件架構的概念有兩個:workspacepackage

workspace是表示整個項目的,也叫repo,必須在項目的根目錄下建一個WORKSPACE文件來定義項目的根目錄,bazel會忽略所有項目子目錄下的WORKSPACE文件。

package是項目中的模塊,也就是一個一個包,包在組織上比較隨意,可以根據項目需求來定,你想哪個文件夾中的東西成爲一個包,就在那個文件夾的目錄裏創建一個BUILD文件即可,包的管理範圍包括子目錄裏的東西,但不包括子包所包括的內容。比如:

.../project/
	WORKSPACE
	lib/
		BUILD
		...
	src/
		BUILD
		...
		other1/
			BUILD
		other2/
			...

則lib, src以及other1都是packages,但other1目錄裏的東西不屬於src包,但other2裏的東西都屬於src包。包和包之間的內容不重疊,不包含。
引用一個包寫全了是這樣的:

@[project_name]//[path/to/package]

比如上面的三個包:

@project//lib
@project//src
@project//src/other1

後面會提到其他簡化寫法,但我覺得一開始明白這個完整形態是很重要的。

三、bazel的運行架構

首先明白bazel的運行架構我覺得會讓學習bazel做到心中有數。bazel自動化構建代碼時大體分爲三個步驟:

  1. 加載階段:load phase
  2. 分析階段:analysis phase
  3. 執行階段:execution phase

加載階段:
bazel在構建時我認爲只會執行BUILD文件,這個文件可以理解成一個腳本,指導bazel如何去構建這個package中的代碼,將他們變成二進制可執行文件。但bazel的文件其實不止只有WORKSPACEBUILD,還有很多.bzl文件,這些文件可以理解成類似於c裏面的頭文件一樣,爲了讓BUILD文件看起來簡潔,工整,所以把很多其他東西以及定義之類的內容,扔到了.bzl文件裏,然後在BUILD文件開始處通過一個load命令將需要的東西包含進來,類似於#include,所以開發bazel的人限制了BUILD文件中可以使用的語法,而在.bzl文件中沒有限制。

以上說的這些廢話,就是在加載階段完成的,加載階段做的就是替換代碼,展開代碼,類似於#include乾的事,還有一些比如宏(Macro)展開之類的事情也在這一階段完成,宏在後面會說。

分析階段:
加載階段結束後,我覺得此時可以認爲我們只有BUILD文件需要考慮了,而且是一個展開完全的BUILD文件,這其中都是一個一個的函數調用,每一個函數調用定義一個對象,每一個對象都包含一個label(這個label的概念很重要,他是bazel的一種基本數據結構,不是string那麼簡單),由name域的傳參決定。這些對象功能各樣,有的是定義了一個行爲(稱爲rule,規則),有的是定義了一個文件或一組文件,有的定義了一組配置等等,後面細說。類似如下,不同的函數需要的參數也是不同的:

cc_binary(name="hahaha",srcs=["hello.cc"],deps=[":enenen"])
cc_library(name="enenen",srcs=[......],hdrs=[......])
config_setting(name="x86",values={"cpu","x86"})

分析階段就是來執行這些函數,生成(我的理解)一個靜態有向圖,就好像tensorflow那個靜態圖的概念,每一個函數都生成靜態圖中的一個結點,根據結點中定義的label和其他信息,構建結點之間的依賴關係。比如上面那個"hahaha"是個label,“enenen"也是一個label,然後"hahaha"依賴於"enenen”。

分析階段只是建立這種依賴關係的有向圖,定義這些對象,但不會確切的執行任何構建工作,它只是分配了工作順序,就好像一個工廠把人員各就各位了,但大家都沒開始工作,等到execution phase,大家一起開工。

執行階段
也就是老闆喊了聲 “各就各位,幹”,然後大家每個對象就各司其職,自己不依賴別人的對象就直接開幹了,依賴別人的對象就等別人幹好了把需要的材料送過來再開幹。所以在這個階段纔會開始構建項目,輸出各種文件,執行各種IO操作。

-----------------------------------下一節開始細節------------------------------------------

發佈了12 篇原創文章 · 獲贊 52 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章