Bazel 可以依賴其他專案的目標。彼此的依附元件 稱為外部依附元件
憑證中的 WORKSPACE
檔案 (或 WORKSPACE.bazel
檔案)
工作區目錄
告知 Bazel 如何取得其他專案資料來源這些其他專案
包含一或多個 BUILD
檔案,且有各自的目標。以下資料夾中有 BUILD
個檔案
主要專案可以依附於這些外部目標
WORKSPACE
檔案。
舉例來說,假設系統中有兩個專案:
/
home/
user/
project1/
WORKSPACE
BUILD
srcs/
...
project2/
WORKSPACE
BUILD
my-libs/
如果 project1
需要使用目標 :foo
,
/home/user/project2/BUILD
,它可以指定名為
在 /home/user/project2
找到 project2
。然後指定
/home/user/project1/BUILD
可能依附於 @project2//:foo
。
WORKSPACE
檔案可讓使用者依附於
或是從網際網路下載的檔案使用的語法與 BUILD
相同
但是允許另一組稱為「存放區規則」的規則 (有時
也稱為 工作區規則)。Bazel 提供了幾個內建存放區
規則以及一組嵌入式 Starlark 存放區
規則。使用者也可以編寫自訂存放區
規則,即可進行更複雜的行為。
支援的外部依附元件類型
可使用的外部依附元件分為幾種基本類型:
依附於其他 Bazel 專案
如要使用第二個 Bazel 專案中的目標
使用
local_repository
、
git_repository
。
或 http_archive
建立符號連結、參照 Git 存放區或下載
可以分別使用
舉例來說,假設您正在處理 my-project/
專案
需要使用您在同事專案 coworkers-project/
中的目標。兩者皆有
專案使用 Bazel,因此您可以將同事的專案新增為
然後使用同事自行定義的目標
BUILD 檔案。請將以下內容新增到 my_project/WORKSPACE
:
local_repository(
name = "coworkers_project",
path = "/path/to/coworkers-project",
)
如果同事指定的是//foo:bar
,則可將專案稱為
@coworkers_project//foo:bar
。外部專案名稱必須是
有效的工作區名稱。
取決於非 Bazel 專案
前置字串為 new_
的規則,例如
new_local_repository
,
可讓您在不使用 Bazel 的專案中建立目標
舉例來說,假設您正在處理 my-project/
專案
要使用的專案:coworkers-project/
。您同事的
專案使用 make
進行建構,但您想依附其中一個 .so 檔案
所產生的費用若要這樣做,請在 my_project/WORKSPACE
中新增以下內容:
new_local_repository(
name = "coworkers_project",
path = "/path/to/coworkers-project",
build_file = "coworker.BUILD",
)
build_file
會指定要疊加在現有專案上的 BUILD
檔案,
範例:
cc_library(
name = "some-lib",
srcs = glob(["**"]),
visibility = ["//visibility:public"],
)
接著,您可以從專案內依附 @coworkers_project//:some-lib
BUILD
個檔案。
視外部套件而定
Maven 構件和存放區
使用規則集 rules_jvm_external
從 Maven 存放區下載構件,並以 Java 格式提供構件
依附元件
擷取依附元件
根據預設,系統會在 bazel build
期間視需要擷取外部依附元件。如果
如要預先擷取一組特定目標所需的依附元件,請使用
bazel fetch
。
如要無條件擷取所有外部依附元件,請使用
bazel sync
。
擷取的存放區會儲存在輸出基準中,
在每個工作區中發生一次
覆蓋依附元件
建議您盡可能在 專案。您必須對依附元件進行編譯,最後才能編譯依附元件 作為最終二進位數字。但如果不這樣做 影子依附元件請參考下列情境:
我的專案/工作區
workspace(name = "myproject")
local_repository(
name = "A",
path = "../A",
)
local_repository(
name = "B",
path = "../B",
)
空調
workspace(name = "A")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "testrunner",
urls = ["https://github.com/testrunner/v1.zip"],
sha256 = "...",
)
B/工作區
workspace(name = "B")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "testrunner",
urls = ["https://github.com/testrunner/v2.zip"],
sha256 = "..."
)
A
和 B
都依附於 testrunner
,但兩者相依
不同的 testrunner
版本這些測試執行工具沒有理由
不平靜在 myproject
內共存,但是它們會與
因為兩者的名稱相同如要宣告這兩個依附元件
更新 myproject/WORKSPACE:
workspace(name = "myproject")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "testrunner-v1",
urls = ["https://github.com/testrunner/v1.zip"],
sha256 = "..."
)
http_archive(
name = "testrunner-v2",
urls = ["https://github.com/testrunner/v2.zip"],
sha256 = "..."
)
local_repository(
name = "A",
path = "../A",
repo_mapping = {"@testrunner" : "@testrunner-v1"}
)
local_repository(
name = "B",
path = "../B",
repo_mapping = {"@testrunner" : "@testrunner-v2"}
)
這個機制也可用來加入鑽石。例如 A
和 B
具有相同依附元件,但用不同的名稱呼叫,這些依附元件
加入 myproject/WORKSPACE 中
透過指令列覆寫存放區
如要透過指令列使用本機存放區覆寫宣告的存放區,
請使用
--override_repository
敬上
旗標。使用此旗標時,系統會變更外部存放區的內容
並變更原始碼
舉例來說,如要將 @foo
覆寫為本機目錄 /path/to/local/foo
,
傳遞 --override_repository=foo=/path/to/local/foo
標記。
以下列舉幾個用途:
- 偵錯。舉例來說,您可以覆寫
http_archive
存放區 到本機目錄,方便您進行變更 - 供應商。如果您所在的環境無法進行網路呼叫, 覆寫以網路為基礎的存放區規則,指向本機目錄 。
使用 Proxy
Bazel 會從 HTTPS_PROXY
和 HTTP_PROXY
挑選 Proxy 位址
環境變數,並使用這些環境變數來下載 HTTP/HTTPS 檔案 (如有指定)。
支援 IPv6
在僅支援 IPv6 的機器上,Bazel 可以用
沒有變更不過,在雙重堆疊 IPv4/IPv6 機器上,Bazel 會採用相同的
都採用 Java 的慣例:如果啟用 IPv4,系統會優先使用 IPv4。在某些情況下
例如:IPv4 網路無法解析/連線至外部位址時
這可能會導致 Network unreachable
例外狀況並建構失敗。
在這種情況下,您可以覆寫 Bazel 的行為,優先使用 IPv6
使用 java.net.preferIPv6Addresses=true
系統資源。
詳細說明:
使用「
--host_jvm_args=-Djava.net.preferIPv6Addresses=true
」 啟動選項 例如,在.bazelrc
檔案:startup --host_jvm_args=-Djava.net.preferIPv6Addresses=true
如果您執行的 Java 建構目標需要連上網際網路 (整合測試有時需要)
--jvmopt=-Djava.net.preferIPv6Addresses=true
工具旗標,例如.bazelrc
的下一行:build --jvmopt=-Djava.net.preferIPv6Addresses
如果使用 rules_jvm_external, 舉例來說,如需依附元件版本解析,請將
-Djava.net.preferIPv6Addresses=true
到COURSIER_OPTS
環境變數,為 Coursier 提供 JVM 選項
遞移依附元件
Bazel 只會讀取 WORKSPACE
檔案中列出的依附元件。如果您的專案
(A
) 依附於另一個專案 (B
),該專案列出三個依附元件
專案 (C
),請在其 WORKSPACE
檔案中新增兩個 B
並將 C
加入專案的 WORKSPACE
檔案這項規定可能會使
WORKSPACE
的檔案,但會限制只有一個程式庫的機率
包括版本 1.0 的 C
,另一個版本則包含 C
2.0 版。
快取外部依附元件
根據預設,Bazel 只會在符合以下條件的情況下重新下載外部依附元件
定義變更定義中參照的檔案 (例如修補程式)
或 BUILD
檔案) 也會將 bazel 納入考量。
如要強制重新下載,請使用 bazel sync
。
版面配置
外部依附元件全部下載至子目錄下的目錄
輸出基準中的 external
。如果
本機存放區,系統會建立符號連結
不必建立新目錄
您可以執行下列指令來查看 external
目錄:
ls $(bazel info output_base)/external
請注意,執行 bazel clean
並不會刪除外部外部 IP 位址
目錄。如要移除所有外部構件,請使用 bazel clean --expunge
。
離線版本
有時候是理想或需要離線執行建構。適用對象
像是搭乘飛機
prefetching所需的資料
含有 bazel fetch
或 bazel sync
的存放區就足夠了;另外,
使用 --nofetch
選項,可停用擷取其他存放區的功能
建構期間
如果是真正的離線版本,就必須提供必要檔案
一個與 bazel 不同的實體,bazel 可以支援
--distdir
。每當存放區規則要求 bazel 透過以下方式擷取檔案時
ctx.download
或
ctx.download_and_extract
。
並提供檔案的雜湊總和
bazel 會先查看該選項指定的目錄
符合第一個網址基準名稱的檔案,然後使用該本機副本
(如果雜湊相符)。
Bazel 本身會使用這項技術,從發行
Artifact。
方法在於收集所有需要的外部
依附元件
在內部
distdir_tar
。
然而,bazel 允許在存放區規則中執行任意指令。 而無從得知他們是否呼叫網路因此 bazel 無法選擇 強制將建構作業完全離線因此,測試建構能正常運作 離線需要進行外部封鎖 如同 bazel 所在 啟動測試。
最佳做法
存放區規則
存放區規則通常應負責:
- 偵測系統設定並寫入檔案。
- 尋找系統上的其他位置資源。
- 從網址下載資源。
- 將 BUILD 檔案產生或符號連結到外部存放區目錄中。
請盡量避免使用 repository_ctx.execute
。例如,使用非 Bazel C++ 時
如果程式庫使用 Make 建構,建議使用 repository_ctx.download()
,然後
撰寫會建立該檔案的 BUILD 檔案,而不是執行 ctx.execute(["make"])
。
偏好 http_archive
使用 git_repository
,以及
new_git_repository
。原因如下:
- Git 存放區規則依附於系統
git(1)
,HTTP 下載工具則是建立 且沒有系統依附元件。 http_archive
支援urls
清單做為鏡像,而git_repository
僅支援 單一remote
。http_archive
可使用存放區快取,但不支援git_repository
。詳情請見 #5116。
不要使用 bind()
。請參閱「考慮移除
bind」長時間
討論其問題和替代方案。