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

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

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

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

$ 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](/versions/6.2.0/reference/be/general#test_suite) नियमों की ऐक्सेस नहीं होती, क्योंकि ये टारगेट कॉन्फ़िगर नहीं होते. पुरानी जानकारी के लिए, [aquery](/versions/6.2.0/docs/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

होस्ट कॉन्फ़िगरेशन, खास आईडी (HOST) का इस्तेमाल करता है. जनरेट नहीं की गई सोर्स फ़ाइलें, जो आम तौर पर srcs में मिलती हैं, खास आईडी (null) का इस्तेमाल करती हैं (क्योंकि उन्हें कॉन्फ़िगर करने की ज़रूरत नहीं होती).

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

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

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

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

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

# Analyzes //foo in the target configuration, but also analyzes
# //genrule_with_foo_as_tool which depends on a host-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 (HOST)

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

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

फ़ंक्शन

query पर काम करने वाले फ़ंक्शन के सेट में से cquery, visible, siblings, buildfiles, और tests को छोड़कर बाकी सभी के साथ काम करता है.

cquery में ये नए फ़ंक्शन भी दिए गए हैं:

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

expr ::= config(expr, word)

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

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

उदाहरण:

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

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

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

विकल्प

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

cquery, सामान्य Bazel बिल्ड के साथ काम करता है. इस तरह, बिल्ड के दौरान उपलब्ध विकल्पों का इस्तेमाल किया जा सकता है.

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

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

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

# x/BUILD
genrule(
     name = "my_gen",
     srcs = ["x.in"],
     outs = ["x.cc"],
     cmd = "$(locations :tool) $< >$@",
     tools = [":tool"],
)
cc_library(
    name = "tool",
)

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

क्वेरी टारगेट बनाया गया आउटपुट
bazel cquery "//x:tool" //x:tool //x:tool(targetconfig)
bazel cquery "//x:tool" --universe_scope />x:my_gen" //x:my_gen //x:tool(hostconfig)

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

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

--implicit_deps (बूलियन, default=True)

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

--tool_deps (बूलियन, default=True)

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

--include_aspects (बूलियन, default=True)

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

अगर आपको बड़ी क्वेरी की मेमोरी पर पड़ने वाले असर की चिंता नहीं है, तो अपने bazelrc में इस फ़्लैग को डिफ़ॉल्ट रूप से चालू करें.

अगर डाइमेंशन के अलग-अलग पहलुओं के साथ क्वेरी की जाती है, तो हो सकता है कि टारगेट Y बनाने के दौरान टारगेट X काम न करे. हालांकि, cquery somepath(Y, X) और cquery deps(Y) | grep 'X' का कोई नतीजा नहीं मिलेगा, क्योंकि डिपेंडेंसी किसी पहलू के ज़रिए होती है.

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

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

ट्रांज़िशन

--transitions=lite
--transitions=full

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

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

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

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

--output=proto

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

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

--[no]proto:include_configurations

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

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

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

--output=graph

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

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

--output=files

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

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

--output=starlark

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

'cquery' स्टारलार्क बोली

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

build_options(target)

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

अगर टारगेट कोई इनपुट फ़ाइल है, तो build_options(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 को यह नहीं पता कि बिल्ड किस तरह की ब्रांच चुनता है. इसलिए, सभी ब्रांच को शामिल करते समय, यह अनुमान गलत हो जाता है.
  • cquery के सटीक होने के लिए, query से ज़्यादा ग्राफ़ बनाने की ज़रूरत होती है. खास तौर पर, cquery कॉन्फ़िगर किए गए टारगेट का आकलन करता है, जबकि query सिर्फ़ टारगेट का आकलन करता है. इस प्रोसेस में ज़्यादा समय लगता है और ज़्यादा मेमोरी का इस्तेमाल होता है.
  • cquery के क्वेरी भाषा के मतलब से, ऐसी साफ़-साफ़ जानकारी मिलती है जिससे query बचता है. उदाहरण के लिए, अगर "//foo" दो कॉन्फ़िगरेशन में मौजूद है, तो cquery "deps(//foo)" को किसका इस्तेमाल करना चाहिए? [config](#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, पिछले निर्देशों से बिल्ड ग्राफ़ को अपने-आप वाइप नहीं करता है. इस वजह से, इस पर पिछली क्वेरी से मिले नतीजे लेने का खतरा होता है. उदाहरण के लिए, genquery अपने 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 (host_config)
...

    $ bazel cquery "//foo:tool"
tool(host_config)

समाधान: कॉन्फ़िगर किए गए टारगेट का फिर से विश्लेषण करने के लिए, किसी भी स्टार्टअप विकल्प को बदलें. उदाहरण के लिए, अपने बिल्ड निर्देश में --test_arg=&lt;whatever&gt; जोड़ें.

समस्या हल करना

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

अगर आपको:

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