cquery
เป็นตัวแปรของ query
ที่จัดการselect()
และผลของตัวเลือกการสร้างในกราฟการสร้างอย่างถูกต้อง
ซึ่งทำได้โดยการเรียกใช้ผลลัพธ์ของระยะการวิเคราะห์ของ Bazel ซึ่งผสานรวมเอฟเฟกต์เหล่านี้ ในทางตรงกันข้าม query
จะทำงานเหนือผลลัพธ์ของระยะการโหลดของ Basl ก่อนที่จะมีการประเมินตัวเลือก
เช่น
$ 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.5.0/reference/be/general#test_suite)
เนื่องจากไม่ใช่เป้าหมายที่กำหนดค่าไว้ ดูข้อมูลเกี่ยวกับกรณีแรกได้ที่ [aquery](/versions/6.5.0/docs/aquery)
ไวยากรณ์พื้นฐาน
การเรียกใช้ cquery
แบบง่ายมีลักษณะดังนี้
bazel cquery "function(//target)"
นิพจน์การค้นหา "function(//target)"
ประกอบด้วยรายการต่อไปนี้
function(...)
คือฟังก์ชันที่จะเรียกใช้บนเป้าหมายcquery
รองรับฟังก์ชันส่วนใหญ่ของquery
รวมถึงฟังก์ชันใหม่อีก 2-3 รายการ//target
คือนิพจน์ที่ส่งไปยังฟังก์ชัน ในตัวอย่างนี้ นิพจน์เป็นเป้าหมายง่ายๆ แต่ภาษาที่ใช้ในคำค้นหายังอนุญาตให้ฝังฟังก์ชันได้ด้วย ดูตัวอย่างได้ที่วิธีใช้การค้นหา
cquery
ต้องมีเป้าหมายเพื่อเรียกใช้ผ่านเฟสการโหลดและการวิเคราะห์ cquery
จะแยกวิเคราะห์เป้าหมายที่แสดงในนิพจน์การค้นหา เว้นแต่จะระบุไว้เป็นอย่างอื่น ดู--universe_scope
สําหรับการค้นหาทรัพยากร Dependency ของเป้าหมายการสร้างระดับบนสุด
การกำหนดค่า
บรรทัด:
//tree:ash (9f87702)
หมายความว่า //tree:ash
สร้างขึ้นในการกําหนดค่าที่มีรหัส 9f87702
สําหรับเป้าหมายส่วนใหญ่ ค่านี้คือแฮชแบบทึบของค่าตัวเลือกการสร้างที่กําหนดการกําหนดค่า
หากต้องการดูเนื้อหาทั้งหมดของการกำหนดค่า ให้เรียกใช้คำสั่งต่อไปนี้
$ bazel config 9f87702
การกำหนดค่าโฮสต์ใช้รหัสพิเศษ (HOST)
ไฟล์ต้นฉบับที่ไม่ได้สร้างขึ้น เช่น ไฟล์ที่พบได้ทั่วไปใน srcs
จะใช้รหัสพิเศษ (null)
(เนื่องจากไม่จำเป็นต้องมีการกําหนดค่า)
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 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
รองรับฟังก์ชันทั้งหมดยกเว้น allrdeps
, buildfiles
, rbuildfiles
, siblings
, tests
และ visible
cquery
ยังมีฟังก์ชันใหม่ดังต่อไปนี้
การกำหนดค่า
expr ::= config(expr, word)
ออบเจ็กต์ config
จะพยายามค้นหาเป้าหมายที่กําหนดค่าไว้สําหรับป้ายกํากับที่ระบุโดยอาร์กิวเมนต์แรกและการกําหนดค่าที่ระบุโดยอาร์กิวเมนต์ที่ 2
ค่าที่ถูกต้องสำหรับอาร์กิวเมนต์ที่ 2 คือ 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 ปกติ จึงรับชุดตัวเลือกที่ใช้ได้ในระหว่างการบิลด์
การใช้ตัวเลือกข้อความค้นหา
--universe_scope
(รายการที่คั่นด้วยจุลภาค)
บ่อยครั้งที่ทรัพยากร Dependencies ของเป้าหมายที่กําหนดค่าไว้จะผ่านการเปลี่ยนแปลง ซึ่งทําให้การกำหนดค่าของทรัพยากรเหล่านั้นแตกต่างจากทรัพยากร Dependencies แฟล็กนี้ช่วยให้คุณค้นหาเป้าหมายได้ราวกับว่าเป้าหมายนั้นสร้างขึ้นโดยอิงตามหรืออิงตามแบบเปลี่ยนผ่านของเป้าหมายอื่น เช่น
# x/BUILD genrule( name = "my_gen", srcs = ["x.in"], outs = ["x.cc"], cmd = "$(locations :tool) $< >$@", tools = [":tool"], ) cc_library( name = "tool", )
Genrules จะกำหนดค่าเครื่องมือในการกำหนดค่าโฮสต์ ดังนั้นการค้นหาต่อไปนี้จะสร้างเอาต์พุตต่อไปนี้
การค้นหา | สร้างเป้าหมายแล้ว | เอาต์พุต |
---|---|---|
bazel cquery "//x:tool" | //x:tool | //x:tool(targetconfig) |
bazel cquery "//x:tool" --universe_scope="//x:my_gen" | //x:my_gen | //x:tool(hostconfig) |
หากตั้งค่า Flag นี้ ระบบจะสร้างเนื้อหา หากไม่ได้ตั้งค่าไว้ ระบบจะสร้างเป้าหมายทั้งหมดที่กล่าวถึงในนิพจน์การค้นหาแทน การปิดแบบทางอ้อมของเป้าหมายที่สร้างขึ้นจะใช้เป็นจักรวาลของการค้นหา ไม่ว่าจะด้วยวิธีใด เป้าหมายที่จะสร้างต้องสร้างได้ที่ระดับบนสุด (กล่าวคือ เข้ากันได้กับตัวเลือกระดับบนสุด) cquery
จะแสดงผลลัพธ์ใน Closure แบบโอนของเป้าหมายระดับบนสุดเหล่านี้
แม้ว่าคุณจะสร้างเป้าหมายทั้งหมดในนิพจน์การค้นหาที่ระดับบนสุดได้ก็จริง แต่การไม่สร้างเป้าหมายก็อาจมีประโยชน์ เช่น การตั้งค่า --universe_scope
อย่างชัดแจ้งอาจป้องกันไม่ให้มีการสร้างเป้าหมายหลายครั้งในการกำหนดค่าที่คุณไม่สนใจ นอกจากนี้ยังช่วยระบุเวอร์ชันการกำหนดค่าของเป้าหมายที่คุณต้องการได้ด้วย (เนื่องจากปัจจุบันยังไม่มีวิธีอื่นที่ระบุข้อมูลนี้ได้อย่างสมบูรณ์) คุณควรตั้งค่า Flag นี้หากนิพจน์การค้นหาซับซ้อนกว่า deps(//foo)
--implicit_deps
(บูลีน ค่าเริ่มต้นคือ "จริง")
การตั้งค่า Flag นี้เป็นเท็จจะกรองผลลัพธ์ทั้งหมดที่ไม่ได้ตั้งค่าไว้อย่างชัดเจนในไฟล์ BUILD และ Bazel จะตั้งค่าไว้ที่อื่นแทน ซึ่งรวมถึงการกรองเครื่องมือทางเทคนิคที่แก้ไขแล้ว
--tool_deps
(บูลีน ค่าเริ่มต้นคือ "จริง")
การตั้งค่า Flag นี้เป็นเท็จจะกรองเป้าหมายที่กําหนดค่าไว้ทั้งหมดออก ซึ่งเส้นทางจากเป้าหมายที่ค้นหาไปยังเป้าหมายดังกล่าวจะข้ามการเปลี่ยนระหว่างการกําหนดค่าเป้าหมายกับการกําหนดค่าที่ไม่ใช่เป้าหมาย
หากเป้าหมายที่ค้นหาอยู่ในการกําหนดค่าเป้าหมาย การตั้งค่า --notool_deps
จะแสดงเฉพาะเป้าหมายที่อยู่ในการกําหนดค่าเป้าหมายด้วย หากเป้าหมายที่ค้นหาอยู่ในการกําหนดค่าที่ไม่ใช่เป้าหมาย การตั้งค่า --notool_deps
จะแสดงเฉพาะเป้าหมายในการกําหนดค่าที่ไม่ใช่เป้าหมายเท่านั้น โดยทั่วไปการตั้งค่านี้จะไม่ส่งผลต่อตัวกรองของเครื่องมือทางเทคนิคที่แก้ไขแล้ว
--include_aspects
(บูลีน ค่าเริ่มต้นคือ "จริง")
Aspects สามารถเพิ่ม
ทรัพยากร Dependency เพิ่มเติมไปยังบิลด์ได้ โดยค่าเริ่มต้น cquery
จะไม่ติดตามแง่มุมเนื่องจากทำให้กราฟที่ค้นหาได้ใหญ่ขึ้น ซึ่งจะใช้หน่วยความจํามากขึ้น แต่การปฏิบัติตามคำแนะนำจะให้ผลลัพธ์ที่แม่นยำมากขึ้น
หากไม่กังวลเกี่ยวกับผลกระทบของหน่วยความจำจากการค้นหาขนาดใหญ่ ให้เปิดใช้ Flag นี้โดยค่าเริ่มต้นใน bazelrc
หากคุณค้นหาโดยปิดใช้ด้านต่างๆ อยู่ คุณอาจพบปัญหาเมื่อเป้าหมาย X ล้มเหลวขณะสร้างเป้าหมาย Y แต่ cquery somepath(Y, X)
และ cquery deps(Y) | grep 'X'
ไม่แสดงผลลัพธ์เนื่องจากทรัพยากร Dependency เกิดขึ้นผ่านแง่มุมหนึ่ง
รูปแบบเอาต์พุต
โดยค่าเริ่มต้น cquery จะแสดงผลลัพธ์เป็นรายการคู่ป้ายกำกับและการกำหนดค่าตามลําดับความเกี่ยวข้อง นอกจากนี้ คุณยังมีตัวเลือกอื่นๆ ในการแสดงผลลัพธ์ด้วย
ทรานซิชัน
--transitions=lite --transitions=full
การเปลี่ยนการกําหนดค่าจะใช้ในการสร้างเป้าหมายที่อยู่ภายใต้เป้าหมายระดับบนสุดในการกําหนดค่าที่แตกต่างจากเป้าหมายระดับบนสุด
เช่น เป้าหมายอาจบังคับให้เปลี่ยนเป็นการกําหนดค่าโฮสต์สําหรับข้อกําหนดทั้งหมดในแอตทริบิวต์ tools
ซึ่งเราเรียกว่าการเปลี่ยนแอตทริบิวต์ กฎยังบังคับใช้การเปลี่ยนรูปแบบในการกำหนดค่าของตนเองได้ด้วย ซึ่งเรียกว่าการเปลี่ยนรูปแบบคลาสของกฎ รูปแบบเอาต์พุตนี้จะแสดงข้อมูลเกี่ยวกับทรานซิชัน เช่น ประเภทของทรานซิชันและผลที่มีต่อตัวเลือกการสร้าง
รูปแบบเอาต์พุตนี้ทริกเกอร์โดย Flag --transitions
ซึ่งตั้งค่าเป็น NONE
โดยค่าเริ่มต้น โดยจะตั้งค่าเป็นโหมด FULL
หรือ LITE
ก็ได้ FULL
mode จะแสดงผลข้อมูลเกี่ยวกับการเปลี่ยนคลาสกฎและการเปลี่ยนแอตทริบิวต์ รวมถึงความแตกต่างโดยละเอียดของตัวเลือกก่อนและหลังการเปลี่ยน โหมด LITE
จะส่งออกข้อมูลเดียวกันโดยไม่มีความแตกต่างของตัวเลือก
เอาต์พุตข้อความโปรโตคอล
--output=proto
ตัวเลือกนี้จะทำให้เป้าหมายที่ได้พิมพ์ในรูปแบบบัฟเฟอร์โปรโตคอลไบนารี ดูคำจำกัดความของบัฟเฟอร์โปรโตคอลได้ที่ src/main/protobuf/analysis.proto
CqueryResult
คือข้อความระดับบนสุดที่มีผลลัพธ์ของ cquery โดยจะมีรายการข้อความ ConfiguredTarget
รายการและรายการข้อความ Configuration
ConfiguredTarget
แต่ละรายการมี configuration_id
ที่มีค่าเท่ากับค่าของช่อง id
จากข้อความ Configuration
ที่เกี่ยวข้อง
--[no]proto:include_configurations
โดยค่าเริ่มต้น ผลลัพธ์ cquery จะแสดงข้อมูลการกําหนดค่าเป็นส่วนหนึ่งของเป้าหมายที่กําหนดค่าไว้แต่ละรายการ หากไม่ต้องการใช้ข้อมูลนี้และรับเอาต์พุต Proto ที่มีการจัดรูปแบบเหมือนกับเอาต์พุต Proto ของคำค้นหาทุกประการ ให้ตั้งค่าแฟล็กนี้เป็น "เท็จ"
ดูตัวเลือกเพิ่มเติมเกี่ยวกับเอาต์พุต Proto ได้จากเอกสารประกอบเกี่ยวกับเอาต์พุต Proto ของคําค้นหา
เอาต์พุตกราฟ
--output=graph
ตัวเลือกนี้จะสร้างเอาต์พุตเป็นไฟล์ .dot ที่เข้ากันได้กับ Graphviz ดูรายละเอียดได้ในเอกสารประกอบเกี่ยวกับเอาต์พุตกราฟของ query
cquery
ยังรองรับ --graph:node_limit
และ
--graph:factored
ด้วย
เอาต์พุตไฟล์
--output=files
ตัวเลือกนี้จะพิมพ์รายการไฟล์เอาต์พุตที่สร้างขึ้นโดยแต่ละเป้าหมายที่ตรงกับข้อความค้นหา ซึ่งคล้ายกับรายการที่พิมพ์ไว้ที่ท้ายการเรียกใช้ bazel build
เอาต์พุตจะมีเฉพาะไฟล์ที่โฆษณาในกลุ่มเอาต์พุตที่ขอตามที่กำหนดโดยแฟล็ก --output_groups
แต่จะมีไฟล์ต้นฉบับ
การกําหนดรูปแบบเอาต์พุตโดยใช้ Starlark
--output=starlark
รูปแบบเอาต์พุตนี้จะเรียกใช้ฟังก์ชัน Starlark สําหรับเป้าหมายที่กําหนดค่าไว้แต่ละรายการในผลการค้นหา และพิมพ์ค่าที่การเรียกแสดงผล Flag --starlark:file
จะระบุตำแหน่งของไฟล์ Starlark ที่กําหนดฟังก์ชันชื่อ format
ที่มีพารามิเตอร์เดียว target
ระบบจะเรียกใช้ฟังก์ชันนี้สำหรับเป้าหมายแต่ละรายการในผลการค้นหา หรือคุณจะระบุเฉพาะเนื้อหาของฟังก์ชันที่ประกาศเป็น def format(target): return expr
โดยใช้ Flag --starlark:expr
เพื่อความสะดวกก็ได้
ภาษาถิ่น "cquery" ของ Starlark
สภาพแวดล้อม Starlark ของ cquery แตกต่างจากไฟล์ BUILD หรือ .bzl ซึ่งประกอบด้วย ค่าคงที่และฟังก์ชันในตัวของ Starlark หลักทั้งหมด รวมถึงฟังก์ชันเฉพาะสำหรับ cquery 2-3 รายการที่อธิบายไว้ด้านล่าง แต่ไม่รวม glob
, native
หรือ rule
และจะไม่รองรับคำสั่งโหลด
build_options(target)
build_options(target)
จะแสดงผลแผนที่ซึ่งมีคีย์เป็นตัวระบุตัวเลือกการสร้าง (ดูการกำหนดค่า) และค่าที่เป็นค่า Starlark ระบบจะไม่รวมตัวเลือกการสร้างที่มีค่าที่ไม่ใช่ค่า Starlark ที่ถูกต้องไว้ในแผนที่นี้
หากเป้าหมายเป็นไฟล์อินพุต build_options(target)
จะแสดงผล "ไม่มี" เนื่องจากเป้าหมายไฟล์อินพุตมีการกำหนดค่า Null
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()])"
พิมพ์รายการเส้นทางของไฟล์ทั้งหมดที่ผลิตโดยเป้าหมาย rule ใน //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()]"
พิมพ์ค่าของตัวเลือกบรรทัดคำสั่ง --javacopt
เมื่อสร้าง //foo
bazel cquery //foo --output=starlark \ --starlark:expr="build_options(target)['//command_line_option:javacopt']"
พิมพ์ป้ายกำกับของแต่ละเป้าหมายด้วยเอาต์พุตเพียง 1 รายการ ตัวอย่างนี้ใช้ฟังก์ชัน 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"
มีอยู่ในการกําหนดค่า 2 รายการ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=<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/...
ไม่สามารถสร้างขึ้นด้วย Flag การสร้างที่เลือก) ให้เลิกแพ็กเกจรูปแบบเป็นแพ็กเกจย่อยด้วยตนเองโดยใช้การค้นหาการประมวลผลก่อนดังนี้
# 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 "+" -))"