查詢指南

回報問題 查看來源 Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

本頁說明如何開始使用 Bazel 的查詢語言,追蹤程式碼中的依附元件。

如需語言和 --output 標記的詳細資料,請參閱參考手冊「Bazel 查詢參考資料」和「Bazel cquery 參考資料」。如要取得說明,請在指令列中輸入 bazel help querybazel help cquery

如要在執行查詢時忽略缺少目標等錯誤,請使用 --keep_going 旗標。

找出規則的依附元件

如要查看 //foo 的依附元件,請在 bazel 查詢中使用 deps 函式:

$ bazel query "deps(//foo)"
//foo:foo
//foo:foo-dep
...

這是建構 //foo 所需的所有目標集。

追蹤兩個套件之間的依附元件鏈

程式庫 //third_party/zlib:zlibonly 不在 //foo 的 BUILD 檔案中,但屬於間接依附元件。如何追蹤這個依附元件路徑?這裡有兩個實用函式:allpathssomepath。如果您只關心所建構構件中包含的內容,而非所有可能的工作,也可以使用 --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

如未指定 --output graph (使用 allpaths),您會取得依附元件圖表的扁平化清單。

$ 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

附註:隱含依附元件

BUILD 檔案永遠不會參照 //foo//translations/tools:aggregator。那麼,直接依附元件在哪裡?

部分規則會隱含依附於其他程式庫或工具。舉例來說,如要建構 genproto 規則,您必須先建構通訊協定編譯器,因此每個 genproto 規則都會隱含對通訊協定編譯器的依附元件。這些依附元件不會在建構檔案中提及,但會由建構工具新增。目前尚未提供完整的隱含依附元件集。使用 --noimplicit_deps 可從查詢結果中篩除這些依附元件。如果是 cquery,這會包含已解析的工具鍊。

反向依附元件

您可能想瞭解依附於某個目標的目標集。舉例來說,如果您要變更某些程式碼,可能會想知道即將中斷哪些其他程式碼。您可以使用 rdeps(u, x),在 x 的遞移閉包中,找出 u 內目標的反向依附元件。

Bazel 的 Sky Query 支援 allrdeps 函式,可讓您在指定範圍內查詢反向依附元件。

其他用途

您可以使用 bazel query 分析多個依附元件關係。

What exists ...

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 依附於哪些套件?(What do I need to check out to build 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 樹狀結構中,找出 Java 二進位規則間接依附的某些 JNI (C++) 程式庫定義。

bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
...Now find the definitions of all the Java binaries that depend on them
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,但 //foo:foolib 不依附於這些 //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 的兩個變體?

這項查詢可歸結為:「顯示依附於這兩個程式庫的 //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 底下的哪些規則取決於 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 的路徑,必須依序出現在這個建構版本中。