Bazel 使用嚴謹的配置來儲存 以免造成開發人員混淆本頁面嘗試清楚說明 有些事情能做得到
Bazel output_base
在設計上,bazel build
指令一律不會將檔案寫入專案來源。
目錄 (或其子目錄)。而 Bazel 使用特定使用者專屬
parallel 目錄,用來儲存名為 user_output_root
的所有輸出內容。
的預設值:
- Linux 上的
~/.cache/bazel/_bazel_$USER
。 %HOME%\_bazel_%USERNAME%
(Windows)。
每個執行 bazel
的工作區目錄,都有一個獨立的目錄,名稱為
output_base
會在 user_output_root
下建立,如下所示:
${user_output_root}/<WORKSPACE_HASH>`
其中 <WORKSPACE_HASH>
是一長十六進位雜湊 (從
目錄的絕對路徑)。
由於這個路徑是完全無法預測的
bazel info output_base
會在 Bazel 專案中使用時進行列印。
例如:
$ mkdir -p /tmp/project1 && cd /tmp/project1 && touch WORKSPACE.bazel
$ bazel info output_base
Starting local Bazel server and connecting to it...
/usr/local/google/home/digit/.cache/bazel/_bazel_digit/6c7b78994da78136b5cb6b7607361ad3
$ mkdir -p /tmp/project2 && cd /tmp/project2 && touch WORKSPACE.bazel
$ bazel info output_base
Starting local Bazel server and connecting to it...
/usr/local/google/home/digit/.cache/bazel/_bazel_digit/c37b9d68308ee5abe2f781dd38b733b9
$ mkdir -p /tmp/not-a-project && cd /tmp/not-a-project
$ bazel info output_base
WARNING: Invoking Bazel in batch mode since it is not invoked from within a workspace (below a directory having a WORKSPACE file).
ERROR: The 'info' command is only supported from within a workspace (below a directory having a WORKSPACE file).
See documentation at https://bazel.build/concepts/build-ref#workspace
這個配置很有彈性,但不盡完美:
Pro:同一部機器上的多位使用者可以共用相同的唯讀權限 專案目錄
Pro:同一位使用者一律會使用多個專案目錄 獨立的輸出路徑
Con:直接透過指令列查看產生的檔案 圖形探索工具非常困難。
Con:移除專案目錄 (例如使用
rm -rf .../my-project
) 不會移除輸出的內容 (這是重要的廢棄物來源)。Con:移動專案目錄 (例如透過
mv my-project my-project2
) 不會重複使用先前的output_base
內容 (並保留舊內容) 目前無法存取)。Con:
user_output_root
的預設位置,因此output_base
通常不位於相同的檔案系統 / 分區上 專案。這可能會對效能 / 磁碟造成非預期的結果 。
呼叫 bazel clean
即可從目前的 output_base
移除建構輸出內容。
這項操作必須先完成,才能移除來源專案目錄。
實務上,您可以輕鬆使用以下程式碼建構 user_output_root
的內容:
建構出從未經過適當清理的過時 Bazel 專案成果。
更糟的是,手動移除 user_output_root
可能無法運作。
因為 Bazel 預設會建立唯讀建構構件
例如 rm -rf ~/.cache/bazel
執行指令!
Bazel output_base
內容:
許多內容實際上都儲存在 output_base
底下:
外部存放區的 Workspace 目錄:
這些項目對應外部專案依附元件。這類項目通常不屬於 專案來源樹狀結構,但從網路下載或產生 編寫程式
他們的內容會儲存在「
${output_base}/external/<repository_name>
」底下, 其中external
部分是硬式編碼,而<repository_name>
則符合 外部存放區的正規名稱版本構件:
執行
bazel build
產生的檔案。這些資料會儲存在以下位置:${output_base}/execroot/<workspace_name>/bazel-out/<config_dir>/bin/
地點:
execroot
、bazel-out
和bin
部分為硬式編碼,因此無法使用 已變更。針對專案專屬
BUILD.bazel
檔案中定義的目標,<workspace_name>
預設為__main__
,除非在專案的WORKSPACE.bazel
檔案,其中包含類似下方的指令:
workspace( name = "my_project", ) ``` - For targets defined in external repositories, `<workspace_name>` matches the repository's canonical name. - The `<config_dir>` value is a name derived from the build configuration used to configure the target that generated the build artifact. This allows rebuilding the same target in different ways, each time using a different `<config_dir>` value. Note: The `<config_dir>` value is **generally unpredictable**. More on this [here][bazel-config-dirs]
測試結果:
呼叫
bazel test
時產生的記錄檔,儲存在下方${output_base}/execroot/<workspace_name>/bazel-out/<config_dir>/testlogs/
。內部快取和設定檔:
可供遠端建構作業和遠端快取功能使用。您可以按照 開發人員。
Bazel execroot
目錄:
execroot
可用來執行可產生建構構件的 Bazel 指令。
其運作方式取決於是否為特定動作啟用沙箱機制。
在 Linux 上,所有動作都會預設啟用沙箱機制。 Windows 不提供沙箱支援 (自 Bazel 7 起)。
Bazel 動作可以明確使用 「
no-sandbox
」標記的定義。您可以採用下列選項,全面停用沙箱機制: 叫用
bazel
時為--spawn_strategy=local
。
不使用沙箱機制:
停用沙箱機制時,所有會產生構件的建構動作
在特定工作區中
${output_base}/execroot/<workspace_name>
。
動作的 就會使用這個詞彙
Bazel 可確保該指令使用的輸入來源產生符號連結, 。
舉例來說,會編譯 //src/foo/foo.cc
檔案的動作
其中包含 #include "foo.h"
,對應 //src/foo/foo.h
可以
如下所示:
gcc -c -o bazel-out/k8-fastbuild/bin/src/foo/foo.o src/foo/foo.cc -Isrc/foo
這麼做的原因:
在執行指令之前,Bazel 會建立符號連結
${output_base}/execroot/__main__/src
指向$PROJECT/src
, 如此一來,src/foo/foo.cc
和src/foo/foo.h
就會解析為 預期有$PROJECT/src/foo/foo.cc
和$PROJECT/src/foo/foo.h
。bazel-out/k8-fastbuild/bin/src/foo/foo.o
位置是最終結果 將foo.cc
建立 Deployment 設定
採用沙箱機制:
啟用沙箱機制時,Bazel 會為每個指令建立
目錄 (例如 ${output_base}/sandbox/linux-sandbox/<random-number>
)
會建立符號連結樹狀結構來模仿其下方的 execroot 版面配置
只會對已知的輸入值產生影響在此情況下,如下所示:
輸入來源的符號連結
${sandbox}/execroot/__main__/src/foo/foo.cc
和${sandbox}/execroot/__main__/src/foo/foo.h
指向$PROJECT/src/foo/foo.cc
和$PROJECT/src/foo/foo.h
。在
${sandbox}/execroot/__main__
下執行完全相同的指令。 而不是${output_base}/execroot/__main__
。指令完成後,請複製位於 的沙箱路徑中已知的輸出內容
${sandbox}/execroot/__main__/bazel-out/k8-fastbuild/bin/src/foo/foo.o
最終位置${output_base}/execroot/__main__/bazel-out/k8-fastbuild/bin/src/foo/foo.o
。最後,沙箱目錄,以及其中所有的內容都會遭到移除。這也 表示系統會忽略未宣告的輸出內容。