本頁面將說明如何開始使用 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 規則,您必須先建構 Protocol Compiler,因此每個 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
依附元件規則
bar 依賴哪些 genproto 規則?
bazel query 'kind(genproto, deps(bar/...))'
找出 Servlet 樹狀結構中某些 JNI (C++) 程式庫的定義,這些程式庫會間接依附於 Java 二進位規則。
bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
...現在找出所有依附此類別的 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 實際工作環境二進位檔不依附的 C++ 程式庫有何不同?
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?
這項查詢的本質是:「請顯示 //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 的最長路徑,但可以找到 (或說是 ) 離起點最遠的節點,或是顯示從 x 到其依附的每個 y 的最長路徑長度。使用 maxrank:
bazel query 'deps(//foo-tests)' --output maxrank | tail -1 85 //third_party/zlib:zutil.c
結果表示此版本中存在長度為 85 的路徑,且必須依序出現。