文章目錄
- 1. What is bazel?
- 2. bazel的核心原理
- 2.1 bazel的構建模型
- 2.2 bazel的核心概念
- 2.3 bazel的關鍵特性
- 3. bazel的使用
- 3.1 劃分項目結構
- 3.2 編寫BUILD文件
- 3.3 bazel常用命令
- 3.4 bazel依賴管理
- 參考內容
1. What is bazel?
bazel是一個開源的構建工具,它基于聲明式構建語言和精確的依賴管理,一般大型項目的構建會使用bazel。
2. bazel的核心原理
2.1 bazel的構建模型
- 依賴圖DAG:bazel基于依賴圖構建。bazel將構建過程建模為有向無環圖,每個節點表示一個構建目標(如源文件、庫、二進制等),邊表示依賴關系。(基于依賴圖構建的優勢:重構的時候可僅重新構建受影響的節點,實現高效增量構建)
- 內容尋址存儲CAS:每個構件產物(如.o文件)的哈希值由其內容決定,避免重復構建相同內容。
- 沙箱機制:在隔離環境中執行構建動作(如編譯、鏈接),確保構建過程不受主機環境影響,提升可重現性。
2.2 bazel的核心概念
- WORKSPACE:WORKSPACE文件一般位于項目的根目錄下,用于定義外部依賴和全局配置;
- BUILD:每個目錄下的BUILD文件或BUILD.bazel文件,用于聲明本目錄的構建目標(如cc_library)
- Target:目標,是BUILD文件中定義的最小構建單元,比如庫、二進制文件等;
- Rule:規則,用于描述如何從輸入(源文件、依賴)生成輸出(如編譯、打包)。
2.3 bazel的關鍵特性
- 增量構建:即僅構建受代碼變更影響的目標;
- 分布式構建:支持將構建任務分發到多臺機器(但需要配置遠程執行環境);
- 遠程緩存:共享構建緩存,加速團隊協作;
- 跨平臺:支持多操作系統,同一構建描述文件可跨平臺使用
3. bazel的使用
3.1 劃分項目結構
首先需要劃分項目結構,確定每個BUILD文件的位置。假設項目結構如下:
my_project/
├── WORKSPACE # 工作區配置文件(可留空)
├── src/
│ ├── main.c # 主程序
│ ├── lib/
│ │ ├── utils.c # 庫源碼
│ │ └── utils.h
│ └── BUILD # 構建規則
└── tests/└── test.c # 測試代碼
3.2 編寫BUILD文件
示例:
# src/BUILD# 定義靜態庫
cc_library(name = "utils", # 目標名稱srcs = ["lib/utils.c"], # 源文件hdrs = ["lib/utils.h"], # 頭文件visibility = ["//visibility:public"], # 對其他目錄可見
)# 定義可執行文件
cc_binary(name = "main", # 目標名稱srcs = ["main.c"], # 主程序源文件deps = [":utils"], # 依賴的庫
)# 定義測試
cc_test(name = "test_utils", # 測試目標名稱srcs = ["test.c"], # 測試代碼deps = [":utils"], # 依賴的庫
)
3.3 bazel常用命令
- 構建目標
# 示例 bazel build //src:main # 用于構建src目錄下的main目標,在BUILD文件中包含對應的target # 命令格式 bazel build [flags] <targets...> # 常用的目標模式 //src:main # 指定具體目標 //src/... # src目錄下的所有目標 //... # 整個工作區所有目標 @repo//path:target # 外部依賴目標
- 運行程序
bazel run //src:main # 構建并運行main目標
- 執行測試
bazel test //src:test_utils
- 清理構建緩存
bazel clean # 清理所有的構建產物
3.4 bazel依賴管理
內部依賴:使用//path/to:target
語法引用項目內目標;
外部依賴:需要在WORKSPACE文件中聲明,并在BUILD文件中使用外部依賴。例如:
當前項目my_project依賴子模塊include,include中包含了my_project依賴的頭文件,在WORKSPACE中聲明:
# new_local_repository規則用于將本地目錄或文件引入bazel工作區作為外部依賴;該規則將普通目錄轉換為bazel倉庫
load("@bazel_tools//tools/build_defs/repo:local.bzl", "new_local_repository")
new_local_repository(name = "include" # 倉庫名稱path = "include" # 絕對路徑或相對路徑build_file = "include.BUILD" # 可選,指定構建規則文件
)
在src/BUILD
文件中引用外部依賴:
cc_binary(name = "main", # 目標名稱srcs = ["main.c"], # 主程序源文件deps = [":utils","@include//:include_headers" # 引用外部依賴。假設include.BUILD中包含了名為include_headers的目標],
)
參考內容
官方文檔: https://bazel.build