कॉन्फ़िगर करने लायक क्वेरी (cquery)

किसी समस्या की शिकायत करें सोर्स देखें Nightly · 7.4 .

cquery, query का एक वैरिएंट है. यह select() और बिल्ड ग्राफ़ पर बिल्ड विकल्पों के असर को सही तरीके से मैनेज करता है.

यह Bazel के विश्लेषण के चरण के नतीजों को चलाकर ऐसा करता है, जो इन इफ़ेक्ट को इंटिग्रेट करता है. इसके उलट, विकल्पों के आकलन से पहले, query, बैजल के लोड होने के चरण के नतीजों पर काम करता है.

उदाहरण के लिए:

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

हर नतीजे में, टारगेट के लिए इस्तेमाल किए गए कॉन्फ़िगरेशन का यूनीक आइडेंटिफ़ायर (9f87702) शामिल होता है.

cquery, कॉन्फ़िगर किए गए टारगेट ग्राफ़ पर चलता है. इसलिए, इसमें बिल्ड ऐक्शन जैसे आर्टफ़ैक्ट के बारे में अहम जानकारी नहीं होती. साथ ही, test_suite नियमों का ऐक्सेस भी नहीं होता, क्योंकि ये कॉन्फ़िगर किए गए टारगेट नहीं हैं. पहली ऐसेट के लिए, aquery देखें.

बेसिक सिंटैक्स

cquery कॉल का सामान्य उदाहरण:

bazel cquery "function(//target)"

क्वेरी एक्सप्रेशन "function(//target)" में ये चीज़ें शामिल होती हैं:

  • function(...), टारगेट पर चलने वाला फ़ंक्शन है. cquery, query के ज़्यादातर फ़ंक्शन के साथ-साथ कुछ नए फ़ंक्शन के साथ भी काम करता है.
  • //target, फ़ंक्शन में डाला गया एक्सप्रेशन है. इस उदाहरण में, एक्सप्रेशन एक आसान टारगेट है. हालांकि, क्वेरी लैंग्वेज में फ़ंक्शन को नेस्ट करने की सुविधा भी होती है. उदाहरणों के लिए, क्वेरी गाइड देखें.

cquery को लोड करने और विश्लेषण के चरणों में चलने के लिए टारगेट की ज़रूरत होती है. जब तक अलग से न बताया जाए, cquery, क्वेरी एक्सप्रेशन में दिए गए टारगेट को पार्स करता है. टॉप-लेवल के बिल्ड टारगेट की डिपेंडेंसी के बारे में क्वेरी करने के लिए, --universe_scope देखें.

कॉन्फ़िगरेशन

लाइन:

//tree:ash (9f87702)

का मतलब है कि //tree:ash को आईडी 9f87702 वाले कॉन्फ़िगरेशन में बनाया गया था. ज़्यादातर टारगेट के लिए, यह कॉन्फ़िगरेशन तय करने वाले बिल्ड विकल्प की वैल्यू का एक ऐसा हैश होता है जिसे समझना मुश्किल होता है.

कॉन्फ़िगरेशन का पूरा कॉन्टेंट देखने के लिए, इसे चलाएं:

$ bazel config 9f87702

9f87702, पूरे आईडी का प्रीफ़िक्स है. ऐसा इसलिए होता है, क्योंकि पूरा आईडी SHA-256 हैश होते हैं, जो लंबे होते हैं और जिन्हें फ़ॉलो करना मुश्किल होता है. cquery, पूरे आईडी के किसी भी मान्य प्रीफ़िक्स को समझता है. यह Git के छोटे हैश की तरह ही होता है. पूरे आईडी देखने के लिए, $ bazel config चलाएं.

टारगेट पैटर्न का आकलन

//foo का cquery का मतलब query से अलग होता है. इसकी वजह यह है कि cquery, कॉन्फ़िगर किए गए टारगेट का आकलन करता है. साथ ही, हो सकता है कि बिल्ड ग्राफ़ में //foo के कई कॉन्फ़िगर किए गए वर्शन हों.

cquery के लिए, क्वेरी एक्सप्रेशन में मौजूद टारगेट पैटर्न, उस पैटर्न से मैच करने वाले लेबल के साथ कॉन्फ़िगर किए गए हर टारगेट का आकलन करता है. आउटपुट तय होता है, लेकिन cquery क्वेरी को क्रम में लगाने के मुख्य अनुबंध के अलावा, किसी और तरह के ऑर्डर की गारंटी नहीं देता.

इससे query के मुकाबले, क्वेरी एक्सप्रेशन के लिए बेहतर नतीजे मिलते हैं. उदाहरण के लिए, इनसे कई नतीजे मिल सकते हैं:

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

अगर आपको यह तय करना है कि किस इंस्टेंस पर क्वेरी करनी है, तो config फ़ंक्शन का इस्तेमाल करें.

टारगेट पैटर्न के बारे में ज़्यादा जानकारी के लिए, query के टारगेट पैटर्न के दस्तावेज़ देखें.

फ़ंक्शन

query के साथ काम करने वाले फ़ंक्शन के सेट में से, cquery में सभी फ़ंक्शन काम करते हैं. हालांकि, allrdeps, buildfiles, rbuildfiles, siblings, tests, और visible काम नहीं करते.

cquery में ये नए फ़ंक्शन भी जोड़े गए हैं:

config

expr ::= config(expr, word)

config ऑपरेटर, पहले आर्ग्युमेंट से दिखाए गए लेबल और दूसरे आर्ग्युमेंट से दिखाए गए कॉन्फ़िगरेशन के लिए, कॉन्फ़िगर किया गया टारगेट ढूंढने की कोशिश करता है.

दूसरे आर्ग्युमेंट के लिए मान्य वैल्यू, null या कस्टम कॉन्फ़िगरेशन हैश हैं. हैश को $ bazel config या किसी पिछले cquery के आउटपुट से वापस पाया जा सकता है.

उदाहरण:

$ bazel cquery "config(//bar, 3732cc8)" --universe_scope=//foo
$ bazel cquery "deps(//foo)"
//bar (exec)
//baz (exec)

$ bazel cquery "config(//baz, 3732cc8)"

अगर तय किए गए कॉन्फ़िगरेशन में, पहले आर्ग्युमेंट के सभी नतीजे नहीं मिलते हैं, तो सिर्फ़ वे नतीजे दिखाए जाते हैं जो मिल सकते हैं. अगर तय किए गए कॉन्फ़िगरेशन में कोई नतीजा नहीं मिलता है, तो क्वेरी पूरी नहीं होती.

विकल्प

बिल्ड करने के विकल्प

cquery, सामान्य बेज़ल बिल्ड पर चलता है और इसलिए बिल्ड के दौरान उपलब्ध विकल्प के सेट को इनहेरिट करता है.

cquery विकल्पों का इस्तेमाल करना

--universe_scope (कॉमा से अलग की गई सूची)

कॉन्फ़िगर किए गए टारगेट की डिपेंडेंसी, अक्सर ट्रांज़िशन से गुज़रती हैं. इस वजह से, उनका कॉन्फ़िगरेशन, डिपेंडेंट से अलग हो जाता है. इस फ़्लैग की मदद से, किसी टारगेट से क्वेरी की जा सकती है, जैसे कि उसे किसी डिपेंडेंसी या किसी दूसरे टारगेट के लिए, ट्रांज़िट पर निर्भरता के तौर पर बनाया गया हो. उदाहरण के लिए:

# 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, अपने टूल को exec कॉन्फ़िगरेशन में कॉन्फ़िगर करते हैं, ताकि नीचे दी गई क्वेरी से ये आउटपुट मिलें:

क्वेरी टारगेट बनाया गया आउटपुट
bazel cquery "//x:tool" //x:tool //x:tool(targetconfig)
बेज़ल Cquery "//x:tool" --universe_scope="//x:my_gen" //x:my_gen //x:tool(execconfig)

अगर यह फ़्लैग सेट है, तो इसके कॉन्टेंट बनाए जाते हैं. अगर यह सेट नहीं है, तो क्वेरी एक्सप्रेशन में बताए गए सभी टारगेट बनाए जाते हैं. बनाए गए टारगेट के ट्रांज़िटिव क्लोज़िंग का इस्तेमाल, क्वेरी की यूनिवर्स के तौर पर किया जाता है. दोनों ही मामलों में, जिन टारगेट को बनाए जाना है वे टॉप लेवल पर बनाए जा सकने चाहिए. इसका मतलब है कि वे टॉप लेवल के विकल्पों के साथ काम करने चाहिए. cquery, इन टॉप-लेवल टारगेट के ट्रांज़िशन क्लोज़र में नतीजे दिखाता है.

भले ही, टॉप लेवल पर क्वेरी एक्सप्रेशन में सभी टारगेट बनाए जा सकते हैं, लेकिन ऐसा न करना फ़ायदेमंद हो सकता है. उदाहरण के लिए, --universe_scope को साफ़ तौर पर सेट करने से, उन कॉन्फ़िगरेशन में कई बार टारगेट बनाने से रोका जा सकता है जिनमें आपकी दिलचस्पी नहीं है. इससे यह भी पता चल सकता है कि आपको टारगेट के किस कॉन्फ़िगरेशन वर्शन की ज़रूरत है. फ़िलहाल, किसी और तरीके से इसकी पूरी जानकारी नहीं दी जा सकती. अगर आपकी क्वेरी एक्सप्रेशन, deps(//foo) से ज़्यादा जटिल है, तो आपको यह फ़्लैग सेट करना चाहिए.

--implicit_deps (बुलियन, डिफ़ॉल्ट=सही)

इस फ़्लैग को 'गलत है' पर सेट करने से, ऐसे सभी नतीजे फ़िल्टर हो जाते हैं जिन्हें बिल्ड फ़ाइल में साफ़ तौर पर सेट नहीं किया गया है. इसके बजाय, बेज़ल ने कहीं और सेट नहीं किया है. इसमें, ठीक किए गए टूलचेन को फ़िल्टर करना भी शामिल है.

--tool_deps (बुलियन, डिफ़ॉल्ट=सही)

इस फ़्लैग को 'गलत' पर सेट करने से, उन सभी कॉन्फ़िगर किए गए टारगेट को फ़िल्टर कर दिया जाता है जिनके लिए, क्वेरी किए गए टारगेट से उन तक का पाथ, टारगेट कॉन्फ़िगरेशन और नॉन-टारगेट कॉन्फ़िगरेशन के बीच ट्रांज़िशन को पार करता है. अगर क्वेरी किया गया टारगेट, टारगेट कॉन्फ़िगरेशन में है, तो --notool_deps सेटिंग सिर्फ़ ऐसे टारगेट दिखाएगी जो टारगेट कॉन्फ़िगरेशन में भी हैं. अगर क्वेरी किया गया टारगेट, नॉन-टारगेट कॉन्फ़िगरेशन में है, तो --notool_deps सेटिंग सिर्फ़ नॉन-टारगेट कॉन्फ़िगरेशन में भी टारगेट दिखाएगी. आम तौर पर, इस सेटिंग से रिज़ॉल्व किए गए टूलचेन को फ़िल्टर करने पर असर नहीं पड़ता.

--include_aspects (बुलियन, डिफ़ॉल्ट=सही)

आसपेक्ट की मदद से जोड़ी गई डिपेंडेंसी शामिल करें.

अगर यह फ़्लैग बंद है, तो cquery somepath(X, Y) और cquery deps(X) | grep 'Y', Y को तब छोड़ देते हैं, जब X सिर्फ़ किसी एस्पेक्ट के ज़रिए उस पर निर्भर करता है.

आउटपुट फ़ॉर्मैट

डिफ़ॉल्ट रूप से, cquery लेबल और कॉन्फ़िगरेशन पेयर की सूची में, नतीजों को डिपेंडेंसी के हिसाब से दिखाता है. नतीजों को दिखाने के लिए, और भी विकल्प हैं.

ट्रांज़िशन

--transitions=lite
--transitions=full

कॉन्फ़िगरेशन ट्रांज़िशन का इस्तेमाल, टॉप लेवल टारगेट के नीचे अलग-अलग कॉन्फ़िगरेशन में टारगेट बनाने के लिए किया जाता है.

उदाहरण के लिए, कोई टारगेट अपने tools एट्रिब्यूट में मौजूद सभी डिपेंडेंसी पर, exec कॉन्फ़िगरेशन में ट्रांज़िशन लागू कर सकता है. इन्हें एट्रिब्यूट ट्रांज़िशन कहा जाता है. नियम अपने कॉन्फ़िगरेशन पर भी ट्रांज़िशन लागू कर सकते हैं. इन्हें नियम क्लास ट्रांज़िशन कहा जाता है. यह आउटपुट फ़ॉर्मैट, इन ट्रांज़िशन के बारे में जानकारी दिखाता है. जैसे, वे किस तरह के हैं और बिल्ड के विकल्पों पर उनका क्या असर पड़ता है.

यह आउटपुट फ़ॉर्मैट, --transitions फ़्लैग से ट्रिगर होता है, जो डिफ़ॉल्ट रूप से NONE पर सेट होता है. इसे FULL या LITE मोड पर सेट किया जा सकता है. FULL मोड, नियम क्लास के ट्रांज़िशन और एट्रिब्यूट के ट्रांज़िशन के बारे में जानकारी दिखाता है. इसमें ट्रांज़िशन से पहले और बाद के विकल्पों के बीच के अंतर की पूरी जानकारी शामिल होती है. LITE मोड, विकल्पों के अंतर के बिना वही जानकारी दिखाता है.

प्रोटोकॉल मैसेज का आउटपुट

--output=proto

इस विकल्प की वजह से, नतीजे के तौर पर मिले टारगेट, बाइनरी प्रोटोकॉल के बफ़र फ़ॉर्म में प्रिंट हो जाते हैं. प्रोटोकॉल बफ़र की परिभाषा src/main/protobuf/analysis_v2.proto पर देखी जा सकती है.

CqueryResult एक टॉप लेवल मैसेज है, जिसमें cquery के नतीजे शामिल हैं. इसमें ConfiguredTarget मैसेज की सूची और Configuration मैसेज की सूची है. हर ConfiguredTarget में एक configuration_id होता है, जिसकी वैल्यू, उससे जुड़े Configuration मैसेज के id फ़ील्ड की वैल्यू के बराबर होती है.

--[no]proto:include_configurations

डिफ़ॉल्ट रूप से, cquery के नतीजे, कॉन्फ़िगर किए गए हर टारगेट के हिस्से के तौर पर कॉन्फ़िगरेशन की जानकारी दिखाते हैं. अगर आपको यह जानकारी नहीं चाहिए और आपको क्वेरी के प्रोटो आउटपुट जैसा ही फ़ॉर्मैट वाला प्रोटो आउटपुट चाहिए, तो इस फ़्लैग को 'गलत' पर सेट करें.

प्रोटो आउटपुट से जुड़े ज़्यादा विकल्पों के लिए, क्वेरी के प्रोटो आउटपुट का दस्तावेज़ देखें.

ग्राफ़ का आउटपुट

--output=graph

यह विकल्प, Graphviz के साथ काम करने वाली .dot फ़ाइल के तौर पर आउटपुट जनरेट करता है. ज़्यादा जानकारी के लिए, query का ग्राफ़ आउटपुट दस्तावेज़ देखें. cquery --graph:node_limit और --graph:factored के साथ भी काम करता है.

फ़ाइलों का आउटपुट

--output=files

यह विकल्प, क्वेरी से मैच होने वाले हर टारगेट से जनरेट हुई आउटपुट फ़ाइलों की सूची को प्रिंट करता है. यह सूची, bazel build को कॉल करने के आखिर में प्रिंट की गई सूची से मिलती-जुलती होती है. आउटपुट में सिर्फ़ वे फ़ाइलें शामिल होती हैं जिनका विज्ञापन अनुरोध किए गए आउटपुट ग्रुप में दिखाया गया है. इन फ़ाइलों को --output_groups फ़्लैग के आधार पर तय किया जाता है. इसमें सोर्स फ़ाइलें शामिल होती हैं.

इस आउटपुट फ़ॉर्मैट से जनरेट होने वाले सभी पाथ, execroot के हिसाब से होते हैं. bazel info execution_root की मदद से, execroot को ऐक्सेस किया जा सकता है. अगर bazel-out सुविधा वाला सिंबललिंक मौजूद है, तो मुख्य रिपॉज़िटरी में मौजूद फ़ाइलों के पाथ, वर्कस्पेस डायरेक्ट्री के हिसाब से भी रिज़ॉल्व होते हैं.

Starlark का इस्तेमाल करके आउटपुट फ़ॉर्मैट तय करना

--output=starlark

यह आउटपुट फ़ॉर्मैट, क्वेरी के नतीजे में कॉन्फ़िगर किए गए हर टारगेट के लिए Starlark फ़ंक्शन को कॉल करता है. साथ ही, कॉल से मिली वैल्यू को प्रिंट करता है. --starlark:file फ़्लैग, Starlark फ़ाइल की जगह की जानकारी देता है. इस फ़ाइल में, format नाम के फ़ंक्शन के बारे में बताया गया है. इसमें एक पैरामीटर, target है. क्वेरी के नतीजे में मौजूद हर टारगेट के लिए, इस फ़ंक्शन को कॉल किया जाता है. इसके अलावा, --starlark:expr फ़्लैग का इस्तेमाल करके, def format(target): return expr के तौर पर एलान किए गए फ़ंक्शन का सिर्फ़ मुख्य हिस्सा बताया जा सकता है.

'cquery' Starlark बोली

cquery Starlark एनवायरमेंट, BUILD या .bzl फ़ाइल से अलग होता है. इसमें Starlark के सभी मुख्य पहले से मौजूद कॉन्स्टेंट और फ़ंक्शन शामिल हैं. साथ ही, इसमें cquery के हिसाब से कुछ खास कॉन्स्टेंट और फ़ंक्शन भी शामिल हैं. हालांकि, इसमें glob, native या rule शामिल नहीं हैं. साथ ही, इसमें लोड स्टेटमेंट काम नहीं करते.

build_options(target)

build_options(target) ऐसा मैप दिखाता है जिसकी कुंजियां विकल्प के आइडेंटिफ़ायर हैं (कॉन्फ़िगरेशन देखें) और जिनकी वैल्यू Starlark की वैल्यू हैं. इस मैप से ऐसे बिल्ड विकल्प हटा दिए जाते हैं जिनकी वैल्यू, Starlark की मान्य वैल्यू नहीं हैं.

अगर टारगेट कोई इनपुट फ़ाइल है, तो build_options(target) None दिखाता है. ऐसा इसलिए होता है, क्योंकि इनपुट फ़ाइल के टारगेट का कॉन्फ़िगरेशन शून्य होता है.

providers(target)

providers(target) एक मैप दिखाता है, जिसकी कुंजियां प्रोवाइडर के नाम (उदाहरण के लिए, "DefaultInfo") होती हैं और जिनकी वैल्यू उनकी Starlark वैल्यू होती हैं. सेवा देने वाली ऐसी कंपनियां जिनके मान कानूनी नहीं हैं, Starlark की वैल्यू इस मैप से हटा दी गई है.

उदाहरण

//foo से जनरेट की गई सभी फ़ाइलों के बेस नेम की सूची को प्रिंट करें. इसमें नामों के बीच स्पेस दिया गया हो:

  bazel cquery //foo --output=starlark \
    --starlark:expr="' '.join([f.basename for f in target.files.to_list()])"

//bar और इसके सबपैकेज में नियम टारगेट के मुताबिक बनाई गई सभी फ़ाइलों के पाथ की सूची, स्पेस से अलग करके बनाई गई हो:

  bazel cquery 'kind(rule, //bar/...)' --output=starlark \
    --starlark:expr="' '.join([f.path for f in target.files.to_list()])"

//foo ने जो भी काम किए हैं उनकी याददाश्त बढ़ाने वाली सूची प्रिंट करें.

  bazel cquery //foo --output=starlark \
    --starlark:expr="[a.mnemonic for a in target.actions]"

cc_library //baz ने जो कंपाइलेशन आउटपुट रजिस्टर किए हैं उनकी सूची प्रिंट करें.

  bazel cquery //baz --output=starlark \
    --starlark:expr="[f.path for f in target.output_groups.compilation_outputs.to_list()]"

//foo बनाते समय, कमांड लाइन के विकल्प --javacopt की वैल्यू प्रिंट करें.

  bazel cquery //foo --output=starlark \
    --starlark:expr="build_options(target)['//command_line_option:javacopt']"

हर टारगेट के लेबल को सिर्फ़ एक आउटपुट के साथ प्रिंट करें. इस उदाहरण में, किसी फ़ाइल में तय किए गए Starlark फ़ंक्शन का इस्तेमाल किया गया है.

  $ 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

हर टारगेट का लेबल प्रिंट करें जो पूरी तरह से Python 3 है. इस उदाहरण में, किसी फ़ाइल में बताए गए Starlark फ़ंक्शन का इस्तेमाल किया गया है.

  $ 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

उपयोगकर्ता की ओर से तय किए गए प्रोवाइडर से वैल्यू निकालें.

  $ 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 बनाम क्वेरी

cquery और query एक-दूसरे के साथ काम करते हैं और अलग-अलग तरह के विषयों पर बेहतरीन कॉन्टेंट बनाते हैं. आपके लिए कौनसा विकल्प सही है, यह तय करने के लिए इन बातों का ध्यान रखें:

  • cquery आपके बनाए गए ग्राफ़ को मॉडल करने के लिए, खास select() ब्रांच को फ़ॉलो करता है. query को यह नहीं पता होता कि बिल्ड किस ब्रांच को चुनता है. इसलिए, सभी ब्रांच को शामिल करने से यह पता नहीं चलता कि बिल्ड कितना सही है.
  • query की तुलना में, cquery कितना सटीक है, इसके लिए ज़्यादा ग्राफ़ बनाना ज़रूरी है. खास तौर पर, cquery कॉन्फ़िगर किए गए टारगेट का आकलन करता है, जबकि query सिर्फ़ टारगेट का आकलन करता है. इसमें ज़्यादा समय लगता है और ज़्यादा मेमोरी का इस्तेमाल होता है.
  • cquery की क्वेरी भाषा के बारे में दी गई जानकारी में अस्पष्टता है, जबकि query में ऐसा नहीं है. उदाहरण के लिए, अगर "//foo" दो कॉन्फ़िगरेशन में मौजूद है, तो "//foo" को किस कॉन्फ़िगरेशन का इस्तेमाल करना चाहिए?cquery "deps(//foo)" इसमें config फ़ंक्शन आपकी मदद कर सकता है.
  • cquery एक नया टूल है. इसलिए, इसका इस्तेमाल कुछ मामलों में नहीं किया जा सकता. ज़्यादा जानकारी के लिए, ऐसी समस्याएं जिनके बारे में पहले से जानकारी है देखें.

पहले से मालूम समस्याएं

cquery "बिल्ड" करने वाले सभी टारगेट का कॉन्फ़िगरेशन एक ही होना चाहिए.

क्वेरी का आकलन करने से पहले, cquery बिल्ड अप को ट्रिगर करता है, ताकि बिल्ड ऐक्शन ठीक उसी समय शुरू हो जाएं जब क्वेरी पूरी हो जाए. यह "बिल्ड" करने वाले टारगेट, डिफ़ॉल्ट रूप से क्वेरी एक्सप्रेशन में दिखने वाले सभी लेबल से चुने जाते हैं. इसे --universe_scope से बदला जा सकता है. इनका कॉन्फ़िगरेशन एक जैसा होना चाहिए.

हालांकि, ये आम तौर पर टॉप-लेवल के "टारगेट" कॉन्फ़िगरेशन को शेयर करते हैं, लेकिन नियम इनकमिंग एज ट्रांज़िशन की मदद से अपना खुद का कॉन्फ़िगरेशन बदल सकते हैं. cquery में यह सुविधा नहीं है.

समाधान: अगर मुमकिन हो, तो --universe_scope को ज़्यादा सख्त स्कोप पर सेट करें. उदाहरण के लिए:

# 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 के लिए कोई सहायता उपलब्ध नहीं है.

नॉन-डेटरमिनिस्टिक आउटपुट.

cquery, पिछले निर्देशों से बिल्ड ग्राफ़ को अपने-आप नहीं मिटाता. इसलिए, यह पिछली क्वेरी के नतीजे दिखा सकता है. उदाहरण के लिए, genrule अपने tools एट्रिब्यूट पर एक एक्सेक ट्रांज़िशन लागू करता है - इसका मतलब है कि यह एक्सेक कॉन्फ़िगरेशन में अपने टूल कॉन्फ़िगर करता है.

इस ट्रांज़िशन का असर अब भी देखा जा सकता है.

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

समस्या हल करने का तरीका: कॉन्फ़िगर किए गए टारगेट का फिर से विश्लेषण करने के लिए, स्टार्टअप का कोई भी विकल्प बदलें. उदाहरण के लिए, अपने बिल्ड कमांड में --test_arg=<whatever> जोड़ें.

समस्या का हल

बार-बार इस्तेमाल होने वाले टारगेट पैटर्न (/...)

अगर आपको:

$ 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.

इससे गलत तरीके से यह पता चलता है कि पैकेज //foo, दायरे में नहीं है. हालांकि, --universe_scope=//foo:app में यह शामिल है. ऐसा, cquery में डिज़ाइन से जुड़ी सीमाओं की वजह से होता है. इसे ठीक करने के लिए, यूनिवर्स के दायरे में //foo/... को साफ़ तौर पर शामिल करें:

$ bazel cquery --universe_scope=//foo:app,//foo/... "somepath(//foo:app, //foo/...)"

अगर ऐसा नहीं होता है (उदाहरण के लिए, //foo/... में मौजूद कुछ टारगेट, चुने गए बिल्ड फ़्लैग के साथ बिल्ड नहीं हो सकते), तो पैटर्न को मैन्युअल तरीके से, प्री-प्रोसेसिंग क्वेरी की मदद से उसके कॉम्पोनेंट पैकेज में अनपैक करें:

# 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 "+" -))"