cquery
, query
varyantının doğru şekilde işleyen bir varyantıdır
select()
ve derleme seçenekleri yapı üzerindeki etkileri
grafiğe dönüştürülebilir.
Bunu, Bazel'in analizinin sonuçları üzerinden
aşamasında
entegre eder. Buna karşılık query
,
Bazel'in seçenekler değerlendirilmeden önceki yükleme aşaması.
Örneğin:
$ cat > tree/BUILD <<EOF sh_library( name = "ash", deps = select({ ":excelsior": [":manna-ash"], ":americana": [":white-ash"], "//conditions:default": [":common-ash"], }), ) sh_library(name = "manna-ash") sh_library(name = "white-ash") sh_library(name = "common-ash") config_setting( name = "excelsior", values = {"define": "species=excelsior"}, ) config_setting( name = "americana", values = {"define": "species=americana"}, ) EOF
# Traditional query: query doesn't know which select() branch you will choose, # so it conservatively lists all of possible choices, including all used config_settings. $ bazel query "deps(//tree:ash)" --noimplicit_deps //tree:americana //tree:ash //tree:common-ash //tree:excelsior //tree:manna-ash //tree:white-ash # cquery: cquery lets you set build options at the command line and chooses # the exact dependencies that implies (and also the config_setting targets). $ bazel cquery "deps(//tree:ash)" --define species=excelsior --noimplicit_deps //tree:ash (9f87702) //tree:manna-ash (9f87702) //tree:americana (9f87702) //tree:excelsior (9f87702)
Her sonuçta benzersiz bir tanımlayıcı (9f87702)
yapılandırmayı
temelini oluşturur.
cquery
, yapılandırılan hedef grafiğin üzerinde çalıştığı için. analiz içermiyor
derleme işlemleri veya test_suite
erişimi gibi yapılara
kuralları yapılandırılmamış hedefler. Birincisi için aquery
sayfasını inceleyin.
Temel söz dizimi
Basit bir cquery
çağrısı şu şekilde görünür:
bazel cquery "function(//target)"
"function(//target)"
sorgu ifadesi şunlardan oluşur:
function(...)
, hedefte çalıştırılacak işlevdir.cquery
. çoğu öğeyi desteklerquery
işlevlerinin yanı sıra bir yenilerini oluşturabilirsiniz.//target
, işleve aktarılan ifadedir. Bu örnekte ifade, basit bir hedeftir. Ancak sorgu dili, işlevlerin iç içe yerleştirilmesine de olanak tanır. Örnekler için Sorgu rehberine bakın.
cquery
, yükleme ve analiz sürecini tamamlaması için bir hedef gerektirir
aşamalar. Aksi belirtilmedikçe cquery
,
sorgu ifadesinden farklıdır. Bkz. --universe_scope
üst düzey derleme hedeflerinin bağımlılıklarını sorgulamak için kullanılır.
Yapılandırmalar
Satır:
//tree:ash (9f87702)
//tree:ash
ürününün, 9f87702
kimliğine sahip bir yapılandırmada oluşturulduğu anlamına gelir. Çoğu
Bu,
yapılandırma.
Yapılandırmanın tüm içeriğini görmek için şu komutu çalıştırın:
$ bazel config 9f87702
9f87702
, tam kimliğin ön ekidir. Bunun nedeni, tam kimliklerin
Uzun ve takip edilmesi zor SHA-256 karmaları. cquery
, geçerli tüm
tam bir kimliğin önekine benzer,
Git kısa karmalar.
Kimliklerin tamamını görmek için $ bazel config
komutunu çalıştırın.
Hedef kalıp değerlendirmesi
//foo
, cquery
için query
dilinden farklı bir anlama sahiptir. Çünkü
cquery
, yapılandırılmış hedefleri değerlendirir ve derleme grafiğinde birden fazla
yapılandırılmış //foo
sürümleri.
cquery
için sorgu ifadesindeki hedef kalıbı
bu kalıpla eşleşen bir etikete sahip her yapılandırılmış hedefe uygulanır. Çıkış (şimdiki değeri)
deterministik, ancak cquery
temel sorgu siparişi sözleşmesi.
Bu, sorgu ifadeleri için query
ile karşılaştırıldığında daha ince sonuçlar üretir.
Örneğin, aşağıdakiler birden fazla sonuç üretebilir:
# Analyzes //foo in the target configuration, but also analyzes # //genrule_with_foo_as_tool which depends on an exec-configured # //foo. So there are two configured target instances of //foo in # the build graph. $ bazel cquery //foo --universe_scope=//foo,//genrule_with_foo_as_tool //foo (9f87702) //foo (exec)
Hangi örneğin üzerinde sorgu yapılacağını kesin olarak belirtmek istiyorsanız
config
işlevini kullanın.
query
adlı kullanıcının hedef kalıbına bakın
dokümanlarına göz atın.
İşlevler
İşlev kümesinin
query
tarafından desteklenir, cquery
şunun hariç tümünü destekler:
allrdeps
,
buildfiles
rbuildfiles
,
siblings
,
tests
ve
visible
.
cquery
aşağıdaki yeni işlevleri de kullanıma sunuyor:
yapılandırma
expr ::= config(expr, word)
config
operatörü, şunun için yapılandırılmış hedefi bulmaya çalışır:
ilk bağımsız değişken ve yapılandırmanın belirttiği
kullanabilirsiniz.
İkinci bağımsız değişken için geçerli değerler null
veya bir
özel yapılandırma karmasını kullanın. Karmalar, $
bazel config
veya önceki cquery
çıkışından alınabilir.
Örnekler:
$ bazel cquery "config(//bar, 3732cc8)" --universe_scope=//foo
$ bazel cquery "deps(//foo)" //bar (exec) //baz (exec) $ bazel cquery "config(//baz, 3732cc8)"
İlk bağımsız değişkenin tüm sonuçları belirtilen yalnızca bulunabilenler döndürülür. Sonuç yoksa belirtilen yapılandırmada bulunursa sorgu başarısız olur.
Seçenekler
Derleme seçenekleri
cquery
, normal bir Bazel derlemesi üzerinde çalışır ve böylece
seçenekleri geliştirmenize yardımcı olur.
Sorgu seçeneklerini kullanma
--universe_scope
(virgülle ayrılmış liste)
Yapılandırılmış hedeflerin bağımlılıkları genellikle geçişler, Bu da yapılandırmalarının bağlı olduklarından farklı olmasına neden olur. Bu işaret , bir hedefi bağımlılık veya geçişli olarak oluşturulmuş gibi sorgulamanıza olanak tanır. bağımlılığı olabilir. Örneğin:
# x/BUILD genrule( name = "my_gen", srcs = ["x.in"], outs = ["x.cc"], cmd = "$(locations :tool) $< >$@", tools = [":tool"], ) cc_binary( name = "tool", srcs = ["tool.cpp"], )
Genrules, araçlarını exec yapılandırması Bu nedenle aşağıdaki sorgular şu çıktıları üretir:
Sorgu | Hedef Oluşturuldu | Çıkış |
---|---|---|
bazel cquery "//x:tool" | //x:tool | //x:tool(targetconfig) |
bazel cquery "//x:tool" --universe_scope="//x:my_gen" | //x:my_gen | //x:tool(execconfig) |
Bu işaret ayarlanırsa içeriği oluşturulur. Belirlenmezse tüm hedefler
belirtilenlerin yerine oluşturmanız gerekir. İşletmenin geçişli olarak kapatılması
oluşturulan hedefler sorgunun evreni olarak kullanılır. Her iki durumda da hedefler
üst düzeyde oluşturulabilmelidir (yani üst düzey
seçenekleri). cquery
, bunların geçişli olarak kapatılmasıyla sonuçlanıyor
üst düzey hedeflerdir.
Üst kısımdaki bir sorgu ifadesinde tüm hedefleri oluşturmak mümkün olsa bile
bu tür bir eylemde bulunmamak yararlı olabilir. Örneğin,
--universe_scope
, şurada hedef oluşturmayı birden çok kez engelleyebilir:
yapılandırmalarına yardımcı olur. Ayrıca, bir dosyanın yapılandırma sürümünün
(şu anda mümkün olmadığı için) aradığınız her şeyi
(bunu başka bir şekilde tam olarak belirtme) gerekir). Bu işareti ayarlamalısınız
(sorgu ifadeniz deps(//foo)
ifadesinden daha karmaşıksa).
--implicit_deps
(boole, varsayılan=Doğru)
Bu işareti false (yanlış) olarak ayarlamak, şurada açıkça belirtilmeyen tüm sonuçları filtreler: BuILD dosyasını kullanır ve bunun yerine Bazel tarafından başka bir yere ayarlanır. Buna çözümlenmiş filtrelemeler dahildir araç zincirleri olarak düşünebilirsiniz.
--tool_deps
(boole, varsayılan=Doğru)
Bu işaretin yanlış değerine ayarlanması,
sorgulanan hedeften bunlara giden yolun hedef ile
ve
hedeflenmeyen yapılandırmalar.
Sorgulanan hedef hedef yapılandırmadaysa --notool_deps
ayarı şunları yapar:
yalnızca hedef yapılandırmada bulunan hedefleri döndürür. Sorgulanan
hedef, hedef olmayan bir yapılandırmada. --notool_deps
ayarı yalnızca şu sonucu döndürür:
hedeflenmeyen yapılandırmalarda da kullanılabilir. Bu ayar genellikle filtrelemeyi etkilemez.
çok basit bir örneğidir.
--include_aspects
(boole, varsayılan=Doğru)
Yönler ile eklenen bağımlılıkları dahil edin.
Bu işaret devre dışı bırakılırsa cquery somepath(X, Y)
ve
X yalnızca bir yönüyle bağımlıysa cquery deps(X) | grep 'Y'
Y'yi atlayın.
Çıkış biçimleri
Varsayılan olarak Cquery çıkışları, bağımlılık sıralı bir etiket ve yapılandırma çifti listesiyle sonuçlanır. Sonuçları göstermek için başka seçenekler de vardır.
Geçişler
--transitions=lite --transitions=full
Yapılandırma geçişleri farklı sektörlerdeki üst düzey hedeflerin altında hedefler oluşturmak için kullanılır. üst düzey hedeflere göre daha fazla yapılandırmaları ortaya çıkarıyor.
Örneğin bir hedef, yönetici yapılandırmasına geçişin tamamını
bağımlılıklarını tools
özelliğinde belirtir. Bunlar,
oluşturabilirsiniz. Kurallar, kendi yapılandırmalarında geçişler de uygulayabilir.
Bunlar, kural sınıfı geçişleri olarak adlandırılır. Bu çıkış biçimi, şunun hakkında bilgi verir:
bunların ne tür olduğu ve bunların derleme üzerindeki etkisi gibi
seçenekleri vardır.
Bu çıkış biçimi, varsayılan olarak --transitions
işareti tarafından tetiklenir.
NONE
olarak ayarlandı. FULL
veya LITE
moduna ayarlanabilir. FULL
modu çıkışı
kural sınıfı geçişleri ve özellik geçişleri hakkında bilgi:
geçişten önceki ve sonraki seçeneklerin ayrıntılı farklarını gösterir. LITE
modu
aynı bilgileri seçenek farkı olmadan çıkarır.
Protokol mesajı çıkışı
--output=proto
Bu seçenek, sonuçta elde edilen hedeflerin ikili program protokolünde yazdırılmasına neden olur bir şablondur. Protokol arabelleğinin tanımı şu adreste bulunabilir: src/main/protobuf/analysis_v2.proto.
CqueryResult
, sorgu sonuçlarını içeren üst düzey mesajdır. Google
ConfiguredTarget
mesaj ve Configuration
mesajdan oluşan bir listeye sahip
mesaj. Her ConfiguredTarget
, değeri eşit olan bir configuration_id
içeriyor
(ilgili Configuration
mesajındaki id
alanının aynısı).
--[no]proto:include_configurations
Varsayılan olarak, Cquery sonuçları her yapılandırılmış hedef. Bu bilgiyi hariç tutup proto çıktısı almak istiyorsanız bu işareti "false" (yanlış) olarak ayarlayın.
Sorgunun proto çıkışı belgelerine bakın. seçenekleri sunar.
Grafik çıkışı
--output=graph
Bu seçenek, çıktıyı Graphviz uyumlu bir .dot dosyası olarak oluşturur. Bkz. query
grafik çıktısı dokümanlarına göz atın. cquery
.
Ayrıca --graph:node_limit
ve
--graph:factored
.
Dosya çıkışı
--output=files
Bu seçenek, eşleşen her hedefin ürettiği çıkış dosyalarının listesini yazdırır
bazel build
etiketinin sonunda yazdırılan listeye benzer sorgu ile
çağrılır. Çıkış yalnızca istekte tanıtılan dosyaları içerir
proje yöneticileri tarafından belirlenen çıkış
--output_groups
işareti.
Kaynak dosyalar bu kapsama girer.
Bu çıkış biçimi tarafından yayınlanan tüm yollar
execroot
bazel info execution_root
üzerinden. bazel-out
kolaylık sembolü bağlantısı varsa
ana depodaki dosyaların yolları da çalışma alanına göre çözümleniyor
dizin.
Starlark'ı kullanarak çıkış biçimini tanımlama
--output=starlark
Bu çıkış biçimi bir Starlark çağırır
işlevini yerine getirir ve
çağrı tarafından geri döndü. --starlark:file
işareti
Tek parametreli format
adlı bir işlevi tanımlayan Starlark dosyası
target
. Bu işlev, her bir Hedef
yazar. Alternatif olarak, kolaylık olması açısından yalnızca
def format(target): return expr
olarak bildirilen bir fonksiyonun gövdesi
--starlark:expr
işareti.
"cquery" Starlark lehçesi
Sorgu Starlark ortamı, BUILD veya .bzl dosyasından farklı. Şunları içerir:
tüm çekirdek Starlark
yerleşik sabit değerler ve işlevler
ve aşağıda açıklanan sorguya özgü birkaç sorguya örnek verilebilir, ancak (örneğin) glob
,
native
veya rule
olarak ayarlanmıştır ve yükleme ifadelerini desteklemez.
build_options(target)
build_options(target)
, anahtarları derleme seçeneği tanımlayıcıları olan bir haritayı döndürür (bkz.
Yapılandırmalar)
olduğunu öğrenmiştiniz. Değerleri yasal Starlark olmayan derleme seçenekleri
değerleri bu haritadan çıkarıldı.
Hedef bir giriş dosyasıysa build_options(target)
, giriş dosyası olarak Yok değerini döndürür
hedeflerin boş bir yapılandırması var.
sağlayıcılar(hedef)
providers(target)
, anahtarları
sağlayıcılar
(örneğin, "DefaultInfo"
) ve değerleri Starlark değerleri olan kullanıcılar. Sağlayıcılar
değerleri yasal Starlark değerleri olmayanlar bu haritadan çıkarılır.
Örnekler
//foo
tarafından üretilen tüm dosyaların temel adlarının boşlukla ayrılmış listesini yazdır:
bazel cquery //foo --output=starlark \ --starlark:expr="' '.join([f.basename for f in target.files.to_list()])"
Kural hedefleri tarafından oluşturulan tüm dosyaların yollarının boşlukla ayrılmış listesini yazdır
//bar
ve alt paketleri:
bazel cquery 'kind(rule, //bar/...)' --output=starlark \ --starlark:expr="' '.join([f.path for f in target.files.to_list()])"
//foo
tarafından kaydedilen tüm işlemlerin anımsatıcılarının listesini yazdırın.
bazel cquery //foo --output=starlark \ --starlark:expr="[a.mnemonic for a in target.actions]"
cc_library
//baz
tarafından kaydedilen derleme çıkışlarının listesini yazdırın.
bazel cquery //baz --output=starlark \ --starlark:expr="[f.path for f in target.output_groups.compilation_outputs.to_list()]"
//foo
oluştururken --javacopt
komut satırı seçeneğinin değerini yazdırın.
bazel cquery //foo --output=starlark \ --starlark:expr="build_options(target)['//command_line_option:javacopt']"
Her hedefin etiketini tam olarak bir çıkışla yazdırın. Bu örnekte, Dosyada tanımlanan Starlark işlevleri.
$ cat example.cquery def has_one_output(target): return len(target.files.to_list()) == 1 def format(target): if has_one_output(target): return target.label else: return "" $ bazel cquery //baz --output=starlark --starlark:file=example.cquery
Her hedefin etiketini (tam olarak Python 3) yazdırın. Bu örnekte, Dosyada tanımlanan Starlark işlevleri.
$ cat example.cquery def format(target): p = providers(target) py_info = p.get("PyInfo") if py_info and py_info.has_py3_only_sources: return target.label else: return "" $ bazel cquery //baz --output=starlark --starlark:file=example.cquery
Kullanıcı tanımlı bir Sağlayıcıdan değer ayıklayın.
$ cat some_package/my_rule.bzl MyRuleInfo = provider(fields={"color": "the name of a color"}) def _my_rule_impl(ctx): ... return [MyRuleInfo(color="red")] my_rule = rule( implementation = _my_rule_impl, attrs = {...}, ) $ cat example.cquery def format(target): p = providers(target) my_rule_info = p.get("//some_package:my_rule.bzl%MyRuleInfo'") if my_rule_info: return my_rule_info.color return "" $ bazel cquery //baz --output=starlark --starlark:file=example.cquery
cquery ve sorgu
cquery
ve query
birbirini tamamlar ve başarılıdır
farklı nişler. Sizin için hangisinin uygun olduğuna karar vermek üzere aşağıdakileri göz önünde bulundurun:
cquery
, aşağıdakileri yapmak için belirliselect()
dallarını takip eder: modeli oluşturmayı öğreneceksiniz.query
hangisinin hangisi olduğunu bilmiyor derlemenin seçtiği bir daldan fazla olmalıdır. Böylece, tüm dalları dahil ederek yaklaşık maksimum değer elde edersiniz.cquery
işlevinin hassasiyeti için daha fazla grafik oluşturmak gerekirquery
yapıyor. Özellikle,cquery
yapılandırılmış hedefleri değerlendirirken yalnızcaquery
hedefleri değerlendirir. Bu işlem daha fazla zaman alır ve daha fazla bellek kullanır.cquery
tarafından yapılan yorum sorgu dili belirsizliğe yol açıyor gibi özelliklerdir.query
Örneğin,"//foo"
iki yapılandırmada mevcutsa hangi yapılandırma?cquery "deps(//foo)"
kullanmalı mı?config
işlevi bu konuda yardımcı olabilir.- Daha yeni bir araç olan
cquery
, belirli kullanımları desteklemiyor durumlarda işe yarar. Ayrıntılar için Bilinen sorunlar başlıklı makaleyi inceleyin.
Bilinen sorunlar
cquery
tarafından "oluşturulan" tüm hedefler aynı yapılandırmaya sahip olmalıdır.
Sorgular değerlendirilmeden önce, cquery
yalnızca
yani derleme işlemlerinin yürütüleceği noktadan önce gelir. Kampanyayı
"yapılar" varsayılan olarak sorguda görünen tüm etiketler arasından seçilir
ifade (bu geçersiz kılınabilir
--universe_scope
ile). Bu
aynı yapılandırmaya sahip olmalıdır.
Bunlar genellikle üst düzey "hedefi" paylaşsa da yapılandırma,
kendi yapılandırmalarını
yaklaşan kenar geçişleri için gösterilir.
cquery
bu noktada yetersiz kalıyor.
Geçici çözüm: Mümkünse --universe_scope
öğesini daha katı bir değere ayarlayın
kapsam. Örneğin:
# This command attempts to build the transitive closures of both //foo and # //bar. //bar uses an incoming edge transition to change its --cpu flag. $ bazel cquery 'somepath(//foo, //bar)' ERROR: Error doing post analysis query: Top-level targets //foo and //bar have different configurations (top-level targets with different configurations is not supported) # This command only builds the transitive closure of //foo, under which # //bar should exist in the correct configuration. $ bazel cquery 'somepath(//foo, //bar)' --universe_scope=//foo
--output=xml
için destek sunulmaz.
Deterministik olmayan çıktı.
cquery
, derleme grafiğini şuradan otomatik olarak silmez:
önceki komutlarda çalışır ve bu nedenle geçmiş sonuçlara ulaşmaya eğilimlidir.
daha fazla bilgi edineceksiniz. Örneğin, genquery
, şurada bir yönetici geçişi uygular:
tools
özelliği ile birlikte, diğer bir deyişle, araçlarını
exec yapılandırması ile ilgili daha fazla bilgi edinin.
Bu geçişin süregelen etkilerini aşağıda görebilirsiniz.
$ cat > foo/BUILD <<<EOF genrule( name = "my_gen", srcs = ["x.in"], outs = ["x.cc"], cmd = "$(locations :tool) $< >$@", tools = [":tool"], ) cc_library( name = "tool", ) EOF $ bazel cquery "//foo:tool" tool(target_config) $ bazel cquery "deps(//foo:my_gen)" my_gen (target_config) tool (exec_config) ... $ bazel cquery "//foo:tool" tool(exec_config)
Geçici çözüm: Yapılandırılmış hedeflerin yeniden analiz edilmesini zorunlu kılmak için tüm başlatma seçeneklerini değiştirin.
Örneğin, derleme komutunuza --test_arg=<whatever>
komutunu ekleyin.
Sorun giderme
Yinelenen hedef kalıpları (/...
)
Aşağıdaki durumlarla karşılaşırsanız:
$ bazel cquery --universe_scope=//foo:app "somepath(//foo:app, //foo/...)" ERROR: Error doing post analysis query: Evaluation failed: Unable to load package '[foo]' because package is not in scope. Check that all target patterns in query expression are within the --universe_scope of this query.
bu, yanlış bir şekilde //foo
paketinin kapsam dahilinde olmadığını gösterir ancak
Bunu --universe_scope=//foo:app
içeriyor. Bunun nedeni,
cquery
Geçici bir çözüm olarak, evrende //foo/...
öğesini açıkça ekleyin
kapsam:
$ bazel cquery --universe_scope=//foo:app,//foo/... "somepath(//foo:app, //foo/...)"
Bu işe yaramazsa (örneğin, //foo/...
ürünündeki bazı hedefler yönlendirilemediği için)
seçilen derleme flag'leriyle derleyin) kalıbı açın, şablonu manuel olarak açın ve
bileşen paketlerinden bahsetmek istiyorum:
# Replace "//foo/..." with a subshell query call (not cquery!) outputting each package, piped into # a sed call converting "<pkg>" to "//<pkg>:*", piped into a "+"-delimited line merge. # Output looks like "//foo:*+//foo/bar:*+//foo/baz". # $ bazel cquery --universe_scope=//foo:app "somepath(//foo:app, $(bazel query //foo/... --output=package | sed -e 's/^/\/\//' -e 's/$/:*/' | paste -sd "+" -))"