本頁說明如何開始使用 Bazel 的查詢語言,在程式碼中追蹤依附元件。
如需語言詳細資料和 --output
旗標的詳細資料,請參閱參考手冊、Bazel 查詢參考資料和 Bazel cquery 參考資料。您可以在指令列中輸入 bazel help query
或 bazel help cquery
來取得說明。
如要在略過缺少目標等錯誤時執行查詢,請使用 --keep_going
旗標。
尋找規則的依附元件
如要查看 //foo
的依附元件,請在 bazel 查詢中使用 deps
函式:
$ bazel query "deps(//foo)" //foo:foo //foo:foo-dep ...
這是建構 //foo
所需的所有目標組合。
追蹤兩個套件之間的依附元件鏈結
//third_party/zlib:zlibonly
程式庫不在 //foo
的 BUILD 檔案中,但這是間接依附元件。如何追蹤這個依附元件路徑?這裡有兩個實用的函式:allpaths
和 somepath
。如果只關注建構的構件包含哪些項目,而非所有可能的工作,建議您透過 --notool_deps
排除工具依附元件。
如要以視覺化方式呈現所有依附元件的圖表,請透過 dot
指令列工具分割 bazel 查詢輸出內容:
$ bazel query "allpaths(//foo, third_party/...)" --notool_deps --output graph | dot -Tsvg > /tmp/deps.svg
如果依附元件圖表太大且複雜,一開始最好使用單一路徑:
$ bazel query "somepath(//foo:foo, third_party/zlib:zlibonly)" //foo:foo //translations/tools:translator //translations/base:base //third_party/py/MySQL:MySQL //third_party/py/MySQL:_MySQL.so //third_party/mysql:mysql //third_party/zlib:zlibonly
如果您並未使用 allpaths
指定 --output graph
,則會取得依附元件圖表的簡化清單。
$ bazel query "allpaths(//foo, third_party/...)" ...many errors detected in BUILD files... //foo:foo //translations/tools:translator //translations/tools:aggregator //translations/base:base //tools/pkg:pex //tools/pkg:pex_phase_one //tools/pkg:pex_lib //third_party/python:python_lib //translations/tools:messages //third_party/py/xml:xml //third_party/py/xml:utils/boolean.so //third_party/py/xml:parsers/sgmlop.so //third_party/py/xml:parsers/pyexpat.so //third_party/py/MySQL:MySQL //third_party/py/MySQL:_MySQL.so //third_party/mysql:mysql //third_party/openssl:openssl //third_party/zlib:zlibonly //third_party/zlib:zlibonly_v1_2_3 //third_party/python:headers //third_party/openssl:crypto
缺點:隱式依附元件
//foo
的 BUILD 檔案一律不會參照 //translations/tools:aggregator
。那麼,直接依附元件在哪裡?
某些規則包含其他程式庫或工具的隱含依附元件。舉例來說,如要建構 genproto
規則,您必須先建構通訊協定編譯器,因此每個 genproto
規則都會在通訊協定編譯器上,提供隱含的依附元件。這些依附元件不會列在建構檔案中,而是由建構工具加入。完整的隱含依附元件組合目前並未記錄。您可以使用 --noimplicit_deps
從查詢結果中篩除這些依附元件。針對 cquery,公開的工具鍊會包含已解析的工具鍊。
反向依附元件
您可能會想知道哪些目標組合取決於某些指定目標。例如,如果您要變更某些程式碼,您可能會想要瞭解要破壞的其他程式碼。您可以使用 rdeps(u, x)
,在 u
遞移封閉內找到 x
中目標的反向依附元件。
Bazel 的 Sky Query 支援 allrdeps
函式,方便您查詢指定範圍中的反向依附元件。
其他用途
您可以使用 bazel query
分析多個依附元件關係。
現有的 ...
foo
下方有哪些套件?
bazel query 'foo/...' --output package
foo
套件中定義的規則為何?
bazel query 'kind(rule, foo:*)' --output label_kind
foo
套件中的規則會產生哪些檔案?
bazel query 'kind("generated file", //foo:*)'
哪些目標是由 Starlark 巨集 foo
產生?
bazel query 'attr(generator_function, foo, //path/to/search/...)'
建構 //foo
需要哪些 BUILD 檔案?
bazel query 'buildfiles(deps(//foo))' | cut -f1 -d:
test_suite
會擴充為哪些個別測試?
bazel query 'tests(//foo:smoke_tests)'
下列哪些是 C++ 測試?
bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'
哪一種是小的?中等?大型?
bazel query 'attr(size, small, tests(//foo:smoke_tests))' bazel query 'attr(size, medium, tests(//foo:smoke_tests))' bazel query 'attr(size, large, tests(//foo:smoke_tests))'
哪些測試符合模式?foo
底下的測試項目為何?
bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))'
模式是一種規則運算式,會套用至規則的完整名稱。就像是
bazel query 'kind(".*_test rule", //foo/...)' | grep -E 'pa?t'
哪個套件包含 path/to/file/bar.java
檔案?
bazel query path/to/file/bar.java --output=package
path/to/file/bar.java?
的建構標籤是什麼?
bazel query path/to/file/bar.java
哪些規則目標含有檔案「path/to/file/bar.java
」做為來源?
fullname=$(bazel query path/to/file/bar.java) bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"
現有的套件依附元件 ...
foo
依附哪些套件?(如要建構 foo
,我需要檢查哪些內容)
bazel query 'buildfiles(deps(//foo:foo))' --output package
foo
樹狀結構依附哪些套件,不包括 foo/contrib
?
bazel query 'deps(foo/... except foo/contrib/...)' --output package
有哪些規則相依性 ...
長條是根據哪些 Genproto 規則運作?
bazel query 'kind(genproto, deps(bar/...))'
找出某些 JNI (C++) 程式庫的定義,這些程式庫將由 Java 二進位規則間接依附於 AVD 樹狀結構中的 Java 二進位規則。
bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
...現在,找出所有依附於 Java 二進位檔的 Java 二進位檔的定義
bazel query 'let jbs = kind(java_binary, //java/com/example/frontend/...) in let cls = kind(cc_.*library, deps($jbs)) in $jbs intersect allpaths($jbs, $cls)'
現有的檔案依附元件 ...
建構 foo 所需的完整 Java 來源檔案有哪些?
來源檔案:
bazel query 'kind("source file", deps(//path/to/target/foo/...))' | grep java$
產生的檔案:
bazel query 'kind("generated file", deps(//path/to/target/foo/...))' | grep java$
建構 QUX 測試時需要哪些 Java 來源檔案的完整組合?
來源檔案:
bazel query 'kind("source file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$
產生的檔案:
bazel query 'kind("generated file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$
X 和 Y 之間的依附元件差異 ...
//foo
有何依附於 //foo:foolib
的功能?
bazel query 'deps(//foo) except deps(//foo:foolib)'
foo
測試哪些 C++ 程式庫是仰賴 //foo
正式版二進位檔「不」仰賴的?
bazel query 'kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo))'
為什麼這個依附元件存在 ...
為什麼 bar
要依賴 groups2
?
bazel query 'somepath(bar/...,groups2/...:*)'
取得這項查詢的結果後,您通常會發現,單一目標特別明顯出自 bar
是非預期或突兀的依附元件。還可進一步將查詢修正為:
顯示從 docker/updater:updater_systest
(py_test
) 到某些 cc_library
的路徑:
bazel query 'let cc = kind(cc_library, deps(docker/updater:updater_systest)) in somepath(docker/updater:updater_systest, $cc)'
為什麼程式庫 //photos/frontend:lib
依附於同一個程式庫 //third_party/jpeglib
和 //third_party/jpeg
的兩個變數?
這項查詢可分為以下類別:「Show me the subgraph of a 隨兩個程式庫依賴」的 //photos/frontend:lib
子圖表。如果按照時間順序顯示,結果的最後一個元素很可能是神奇。
bazel query 'allpaths(//photos/frontend:lib, //third_party/jpeglib) intersect allpaths(//photos/frontend:lib, //third_party/jpeg)' //photos/frontend:lib //photos/frontend:lib_impl //photos/frontend:lib_dispatcher //photos/frontend:icons //photos/frontend/modules/gadgets:gadget_icon //photos/thumbnailer:thumbnail_lib //third_party/jpeg/img:renderer
視 ...
長條底下的哪些規則取決於 Y?
bazel query 'bar/... intersect allpaths(bar/..., Y)'
哪些目標直接依附於 T,在 T 套件中?
bazel query 'same_pkg_direct_rdeps(T)'
如何打破依附元件 ...
若要讓 bar
不再使用 X,我必須中斷哪些依附元件路徑?
如何將圖表輸出至 svg
檔案:
bazel query 'allpaths(bar/...,X)' --output graph | dot -Tsvg > /tmp/dep.svg
其他
//foo-tests
版本有幾個連續步驟?
可惜的是,查詢語言目前無法為您提供從 x 到 y 之間的最長路徑,但可以從起點找出最遠的節點 (或改為 a),或顯示從 x 到每個 y 其所依附的最長路徑長度。使用 maxrank
:
bazel query 'deps(//foo-tests)' --output maxrank | tail -1 85 //third_party/zlib:zutil.c
結果顯示,此建構作業必須依序發生長度為 85 的路徑。