Bazel Sorgusu Nasıl Yapılır?

Sorun bildirin Kaynağı göster

Bu sayfada, kodunuzdaki bağımlılıkları izlemek için Bazel'in sorgu dilini kullanmaya nasıl başlayacağınız açıklanmaktadır.

Dil ayrıntıları ve --output işareti ayrıntıları için lütfen referans kılavuzları, Bazel sorgusu referansını ve Bazel sorgu referansını inceleyin. Komut satırına bazel help query veya bazel help cquery yazarak yardım alabilirsiniz.

Eksik hedefler gibi hataları yok sayarak bir sorgu yürütmek için --keep_going işaretini kullanın.

Bir kuralın bağımlılıklarını bulma

//foo bağımlılarını görmek için bazel sorgusunda deps işlevini kullanın:

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

Bu, //foo oluşturmak için gereken tüm hedefleri içeren kümedir.

İki paket arasındaki bağımlılık zincirini takip etme

//third_party/zlib:zlibonly kitaplığı, //foo için BUILD dosyasında yer almasa da dolaylı bir bağımlılıktır. Bu bağımlılık yolunu nasıl izleyebiliriz? Burada iki yararlı işlev vardır: allpaths ve somepath. Yalnızca derlediğiniz yapıya dahil olanla ve olası her işle değil, yalnızca oluşturduğunuz yapıya nelerin dahil edildiğiyle ilgileniyorsanız --notool_deps ile araç bağımlılıklarını hariç tutmak isteyebilirsiniz.

Tüm bağımlılıkların grafiğini görselleştirmek için dot komut satırı aracıyla bazel sorgu çıkışını ardışık olarak sıralayın:

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

Büyük ve karmaşık olan bir bağımlılık grafiği tek bir yolla başlamak faydalı olabilir:

$ 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 ile --output graph belirtmezseniz bağımlılık grafiğinin düzleştirilmiş bir listesini alırsınız.

$ 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

Bir kenara: Dolaylı bağımlılıklar

//foo için BUILD dosyası, hiçbir zaman //translations/tools:aggregator öğesine referans vermiyor. Peki, doğrudan bağımlılık nerede?

Belirli kurallar, ek kitaplık veya araçlara dolaylı bağımlılıklar içerir. Örneğin, bir genproto kuralı oluşturmak için önce Protokol Derleyici'yi oluşturmanız gerekir. Böylece her genproto kuralı protokol derleyiciye dolaylı bağımlılığı taşır. Bu bağımlılıklar derleme dosyasında bahsedilmez, ancak derleme aracı tarafından eklenir. Dolaylı bağımlılıkların tamamı şu anda belgelenmemiştir. --noimplicit_deps kullanmak, bu yerleşimleri sorgu sonuçlarınızdan filtrelemenize olanak tanır. BigQuery için bu, çözümlenmiş araç zincirlerini içerir.

Ters bağımlılıklar

Bir hedefe bağlı olan hedef kümesini bilmek isteyebilirsiniz. Örneğin, bir kodu değiştirecekseniz, başka hangi kodu kırmak üzere olduğunuzu bilmek isteyebilirsiniz. u geçişli kapanışı içinde x bölgesindeki hedeflerin ters bağımlılıklarını bulmak için rdeps(u, x) kullanabilirsiniz.

Bazel'in Sky Query, belirttiğiniz bir evrendeki ters bağımlılıkları sorgulamanızı sağlayan allrdeps işlevini destekler.

Çeşitli kullanımlar

Birçok bağımlılık ilişkisini analiz etmek için bazel query kullanabilirsiniz.

Mevcut olan ...

foo altında hangi paketler var?

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

foo paketinde hangi kurallar tanımlanır?

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

foo paketindeki kurallar tarafından hangi dosyalar oluşturulur?

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

Hangi hedefler foo Starlark makrosu tarafından oluşturulur?

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

//foo derlemesi için gereken BUILD dosyaları grubu nedir?

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

test_suite öğesinin genişletildiği bağımsız testler nelerdir?

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

Bunlardan hangileri C++ testidir?

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

Bunlardan hangisi küçüktür? Orta? Büyük mü?

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 altında, bir kalıpla eşleşen testler nelerdir?

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

Kalıp bir normal ifadedir ve kuralın tam adına uygulanır. Bu, tıpkı bir web sitesi

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

Hangi paket path/to/file/bar.java dosyasını içeriyor?

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

path/to/file/bar.java? için derleme etiketi nedir?

bazel query path/to/file/bar.java

Hangi kural hedeflerinde kaynak olarak path/to/file/bar.java dosyası bulunur?

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

Hangi paket bağımlılıkları vardır?

foo hangi paketlere bağlıdır? (foo oluşturmak için nelere dikkat etmem gerekiyor?)

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

foo/contrib hariç foo ağacı hangi paketlere bağlıdır?

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

Hangi kural bağımlılıkları vardır?

Çubuk hangi genproto kurallarına bağlıdır?

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

Serlet ağacındaki bir Java ikili kuralının geçişli olarak bağımlı olduğu bazı JNI (C++) kitaplığının tanımını bulun.

bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
...Şimdi bunlara bağlı tüm Java ikili programlarının tanımlarını bulun
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)'

Hangi dosya bağımlılıkları vardır?

Foo'yu derlemek için gereken Java kaynak dosyaları setinin tamamı nedir?

Kaynak dosyalar:

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

Oluşturulan dosyalar:

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

QUX testlerini oluşturmak için gereken Java kaynak dosyaları setinin tamamı nedir?

Kaynak dosyalar:

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

Oluşturulan dosyalar:

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

X ile Y arasındaki bağımlılıklarda ne farklar vardır?

//foo hangi hedefler //foo:foolib buna bağımlı değil?

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

foo testleri, //foo üretim ikili programının bağlı olmadığı hangi C++ kitaplıklarına bağlıdır?

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

Bu bağımlılık neden var?

bar neden groups2 ile ilişkili?

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

Bu sorgunun sonuçlarını aldıktan sonra, genellikle tek bir hedefin beklenmedik, ağır ve istenmeyen bir bar bağımlılığı olduğunu fark edersiniz. Ardından sorgu şu şekilde daha hassas hâle getirilebilir:

docker/updater:updater_systest (bir py_test) ile cc_library arasında bağımlı olan bir yol göster:

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

//photos/frontend:lib kitaplığı neden aynı //third_party/jpeglib ve //third_party/jpeg kitaplığının iki varyantına bağlı?

Bu sorgu, "her iki kitaplığa da bağlı olan //photos/frontend:lib alt grafiğini göster" ile sonuçlanır. Topolojik sırada gösterildiğinde, sonucun son öğesi en olası nedendir.

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

Neye göre değişir?

Çubuğun altındaki hangi kurallar Y'ye bağlıdır?

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

Hangi hedefler T'nin paketinde doğrudan T'ye bağlıdır?

bazel query 'same_pkg_direct_rdeps(T)'

Bir bağımlılığı nasıl kaldırabilirim?

bar ürününün artık X'e bağlı kalmaması için hangi bağımlılık yollarını ayırmam gerekiyor?

Grafiği svg dosyasına dönüştürmek için:

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

Çeşitli

//foo-tests derlemesinde ardışık kaç adım var?

Ne yazık ki sorgu dili şu anda x'ten y'ye en uzun yolu sunamıyor ancak başlangıç noktasından (veya a) en uzak düğümü bulabilir veya x ile y arasındaki en uzun yolun uzunluklarını gösterebilir. maxrank hesabını kullan:

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

Sonuç, bu derlemede sırayla gerçekleşmesi gereken 85 uzunluğunda yolların olduğunu gösterir.