तारीख सेव करें: BazelCon 2023, 24 से 25 अक्टूबर तक Google म्यूनिख में होगा! ज़्यादा जानें

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

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

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(...) फ़ंक्शन, टारगेट पर काम करने के लिए बनाया गया है. cqueryquery के ज़्यादातर फ़ंक्शन के साथ काम करता है. साथ ही, कुछ नए फ़ंक्शन भी काम करता है.
  • //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 में, सभी visible,siblings, buildfiles, और tests काम करते हैं.

cquery ये नए फ़ंक्शन भी पेश करता है:

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

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, आम तौर पर बैज़ल बिल्ड पर चलता है. इसलिए, इसे बनाते समय विकल्प का सेट मिलता है.

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

--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"],
)

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

क्वेरी लक्ष्य बनाया गया आउटपुट
"bazel cquery" "//x:tool" //x:tool //x:tool(targetconfig)
"Bazel cquery" "//x:tool" --uniuni_scope{8}x:my_gen" //x:my_gen //x:tool(execconfig)

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

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

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

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

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

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

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

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

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

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

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

ट्रांज़िशन

--transitions=lite
--transitions=full

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

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

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

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

--output=proto

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

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

--[no]proto:include_configs

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

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

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

--output=graph

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

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

--output=files

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

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

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

--output=starlark

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

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

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

build_options(टारगेट)

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

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

सेवा देने वाली कंपनियां(टारगेट)

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

उदाहरण

//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 और query एक-दूसरे के पूरक हैं और अलग-अलग विषयों से जुड़े हैं. अपने लिए सही विकल्प चुनने के लिए, इन बातों पर ध्यान दें:

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

इस ट्रांज़िशन के दौरान होने वाले असर को यहां देखा जा सकता है.

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