Petunjuk Kueri Bazel

Laporkan masalah Lihat sumber Per Malam · 7,4 kami. 7,3 · 7,2 · 7,1 · 7,0 · 6,5

Halaman ini membahas cara memulai penggunaan bahasa kueri Bazel untuk melacak dependensi dalam kode Anda.

Untuk mengetahui detail bahasa dan detail flag --output, lihat manual referensi, referensi kueri Bazel dan referensi cquery Bazel. Anda bisa mendapatkan bantuan dengan mengetik bazel help query atau bazel help cquery di command line.

Untuk menjalankan kueri sambil mengabaikan error seperti target yang hilang, gunakan metode --keep_going.

Menemukan dependensi aturan

Untuk melihat dependensi //foo, gunakan atribut Fungsi deps dalam kueri bazel:

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

Ini adalah kumpulan semua target yang diperlukan untuk mem-build //foo.

Melacak rantai dependensi antara dua paket

Library //third_party/zlib:zlibonly tidak ada dalam file BUILD untuk //foo, tetapi merupakan dependensi tidak langsung. Bagaimana cara kita melacak jalur dependensi ini? Ada dua fungsi yang berguna di sini: allpaths dan somepath. Anda mungkin juga ingin mengecualikan dependensi alat dengan --notool_deps jika Anda hanya mementingkan apa yang termasuk dalam artefak yang Anda buat, dan tidak semua pekerjaan yang memungkinkan.

Untuk memvisualisasikan grafik semua dependensi, alirkan output kueri bazel melalui alat command line dot:

$ bazel query "allpaths(//foo, third_party/...)" --notool_deps --output graph | dot -Tsvg > /tmp/deps.svg

Jika grafik dependensi besar dan rumit, sebaiknya mulai dengan satu jalur:

$ 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

Jika Anda tidak menentukan --output graph dengan allpaths, Anda akan mendapatkan daftar grafik dependensi yang disatukan.

$ 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

Selain: dependensi implisit

File BUILD untuk //foo tidak pernah mereferensikan //translations/tools:aggregator. Jadi, di mana dependensi langsungnya?

Aturan tertentu menyertakan dependensi implisit pada library atau alat tambahan. Misalnya, untuk membuat aturan genproto, Anda harus terlebih dahulu membuat Protokol Compiler, sehingga setiap aturan genproto membawa dependensi implisit pada kompilator protokol. Dependensi ini tidak disebutkan dalam file build, tetapi ditambahkan oleh alat build. Kumpulan lengkap dependensi implisit saat ini tidak didokumentasikan. Dengan menggunakan --noimplicit_deps, Anda dapat memfilter dependensi ini dari hasil kueri. Untuk cquery, ini akan mencakup toolchain yang di-resolve.

Dependensi terbalik

Anda mungkin ingin mengetahui kumpulan target yang bergantung pada beberapa target. Misalnya, jika Anda akan mengubah beberapa kode, sebaiknya ketahui kode lain yang akan Anda hancurkan. Anda dapat menggunakan rdeps(u, x) untuk menemukan dependensi terbalik target di x dalam penutupan transitif u.

Kueri Sky Bazel mendukung fungsi allrdeps yang memungkinkan Anda untuk mengkueri dependensi balik di alam semesta yang Anda tentukan.

Penggunaan lain-lain

Anda dapat menggunakan bazel query untuk menganalisis banyak hubungan dependensi.

Yang ada ...

Paket apa yang ada di bawah foo?

bazel query 'foo/...' --output package

Aturan apa yang ditentukan dalam paket foo?

bazel query 'kind(rule, foo:*)' --output label_kind

File apa saja yang dibuat oleh aturan dalam paket foo?

bazel query 'kind("generated file", //foo:*)'

Target apa yang dihasilkan oleh makro starlark foo?

bazel query 'attr(generator_function, foo, //path/to/search/...)'

Apa kumpulan file BUILD yang diperlukan untuk membangun //foo?

bazel query 'buildfiles(deps(//foo))' | cut -f1 -d:

Apa saja pengujian individual tempat test_suite diperluas?

bazel query 'tests(//foo:smoke_tests)'

Manakah dari opsi tersebut yang merupakan pengujian C++?

bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'

Manakah dari yang kecil? Sedang? Besar?

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))'

Apa saja pengujian di bawah foo yang cocok dengan suatu pola?

bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))'

Polanya adalah ekspresi reguler dan diterapkan ke nama lengkap aturan. Ini mirip dengan melakukan

bazel query 'kind(".*_test rule", //foo/...)' | grep -E 'pa?t'

Paket apa yang berisi file path/to/file/bar.java?

 bazel query path/to/file/bar.java --output=package

Apa label build untuk path/to/file/bar.java?

bazel query path/to/file/bar.java

Target aturan apa yang berisi file path/to/file/bar.java sebagai sumber?

fullname=$(bazel query path/to/file/bar.java)
bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"

Apa saja dependensi paket yang ada ...

Paket apa yang diandalkan oleh foo? (What do I need to check out to build foo)

bazel query 'buildfiles(deps(//foo:foo))' --output package

Paket apa yang menjadi dependensi hierarki foo, tidak termasuk foo/contrib?

bazel query 'deps(foo/... except foo/contrib/...)' --output package

Dependensi aturan yang ada ...

Aturan genproto apa yang menjadi dasar bar?

bazel query 'kind(genproto, deps(bar/...))'

Temukan definisi beberapa library JNI (C++) yang bergantung secara transitif oleh aturan biner Java di pohon servlet.

bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
...Sekarang temukan definisi semua biner Java yang bergantung padanya
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)'

Apa saja dependensi file yang ada ...

Apa kumpulan lengkap file sumber Java yang diperlukan untuk mem-build foo?

File sumber:

bazel query 'kind("source file", deps(//path/to/target/foo/...))' | grep java$

File yang dihasilkan:

bazel query 'kind("generated file", deps(//path/to/target/foo/...))' | grep java$

Kumpulan file sumber Java apa saja yang diperlukan untuk membuat pengujian QUX?

File sumber:

bazel query 'kind("source file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$

File yang dihasilkan:

bazel query 'kind("generated file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$

Apa saja perbedaan dalam dependensi antara X dan Y yang ada ...

Target apa yang tidak bergantung pada //foo?//foo:foolib

bazel query 'deps(//foo) except deps(//foo:foolib)'

Library C++ apa yang bergantung pada pengujian foo dan tidak bergantung pada biner produksi //foo?

bazel query 'kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo))'

Mengapa ada dependensi ini ...

Mengapa bar bergantung pada groups2?

bazel query 'somepath(bar/...,groups2/...:*)'

Setelah mendapatkan hasil kueri ini, Anda akan sering menemukan bahwa satu target menonjol sebagai dependensi bar yang tidak terduga atau buruk dan tidak diinginkan. Kueri kemudian dapat lebih dipertajam menjadi:

Tampilkan jalur dari docker/updater:updater_systest (py_test) ke beberapa cc_library yang bergantung padanya:

bazel query 'let cc = kind(cc_library, deps(docker/updater:updater_systest)) in
  somepath(docker/updater:updater_systest, $cc)'

Mengapa library //photos/frontend:lib bergantung pada dua varian library yang sama, //third_party/jpeglib dan //third_party/jpeg?

Kueri ini dapat diringkas menjadi: "tampilkan subgrafik //photos/frontend:lib yang bergantung pada kedua library". Ketika ditampilkan dalam urutan topologis, elemen terakhir dari hasilnya adalah penyebab yang paling mungkin.

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

Yang bergantung pada ...

Aturan apa di bawah batang yang bergantung pada Y?

bazel query 'bar/... intersect allpaths(bar/..., Y)'

Target apa yang secara langsung bergantung pada T, dalam paket T?

bazel query 'same_pkg_direct_rdeps(T)'

Bagaimana cara memutus dependensi ...

Jalur dependensi apa yang harus saya hentikan agar bar tidak lagi bergantung pada X?

Untuk menghasilkan grafik ke file svg:

bazel query 'allpaths(bar/...,X)' --output graph | dot -Tsvg > /tmp/dep.svg

Lain-lain

Berapa banyak langkah berurutan yang ada dalam build //foo-tests?

Sayangnya, bahasa kueri saat ini tidak dapat memberi Anda jalur terpanjang dari x ke y, tetapi metode tersebut dapat menemukan (atau lebih tepatnya a) node yang paling jauh dari titik awal, atau tunjukkan panjang jalur terpanjang dari x ke setiap y yang menjadi dependensinya. Gunakan maxrank:

bazel query 'deps(//foo-tests)' --output maxrank | tail -1
85 //third_party/zlib:zutil.c

Hasilnya menunjukkan bahwa ada jalur dengan panjang 85 yang harus terjadi di dalam build ini.