การค้นหาที่กำหนดค่าได้ (cquery)

cquery เป็นตัวแปรของ query ที่จัดการ select() และเอฟเฟกต์ของตัวเลือกบิลด์ได้อย่างถูกต้องในกราฟบิลด์

การบรรลุเป้าหมายนี้มาจากการดูผลลัพธ์ในระยะการวิเคราะห์ของ Bazel ซึ่งผสานรวมผลกระทบเหล่านี้เข้าไว้ด้วยกัน ในทางตรงกันข้าม query จะแสดงผลลัพธ์ในช่วงการโหลดของ Basel ก่อนที่จะมีการประเมินตัวเลือก

เช่น

$ 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 รวมถึงฟังก์ชันใหม่ 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 Shortแฮช หากต้องการดูรหัสทั้งหมด ให้เรียกใช้ $ 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 รองรับทั้งหมดยกเว้น visible, siblings, buildfiles และ tests

นอกจากนี้ cquery ยังนำเสนอฟังก์ชันใหม่ต่อไปนี้ด้วย

การกำหนดค่า

expr ::= config(expr, word)

โอเปอเรเตอร์ config จะพยายามค้นหาเป้าหมายที่กำหนดค่าไว้สำหรับป้ายกำกับที่แสดงโดยอาร์กิวเมนต์แรกและการกำหนดค่าที่ระบุโดยอาร์กิวเมนต์ที่สอง

ค่าที่ถูกต้องสำหรับอาร์กิวเมนต์ที่ 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 ปกติและด้วยเหตุนี้ จึงได้รับชุดตัวเลือกที่ใช้ได้ระหว่างบิลด์

การใช้ตัวเลือก cquery

--universe_scope (รายการที่คั่นด้วยจุลภาค)

บ่อยครั้งที่ทรัพยากร Dependency ของเป้าหมายที่กําหนดค่าไว้จะต้องผ่านการเปลี่ยน ซึ่งทำให้การกําหนดค่าแตกต่างจากองค์ประกอบที่เกี่ยวข้อง แฟล็กนี้ช่วยให้คุณค้นหาเป้าหมายได้เสมือนว่าเป้าหมายนั้นสร้างขึ้นเป็นแบบ Dependency หรือเป็นการอ้างอิงชั่วคราวของเป้าหมายอื่น เช่น

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

หากตั้งค่าแฟล็กนี้ ระบบจะสร้างเนื้อหาขึ้น หากไม่ได้ตั้งค่า ระบบจะสร้างเป้าหมายทั้งหมดที่กล่าวถึงในนิพจน์คำค้นหาแทน การปิดชั่วคราวของเป้าหมายที่สร้างขึ้นจะใช้เป็นจักรวาลของการค้นหา ไม่ว่าจะด้วยวิธีใด เป้าหมายที่จะสร้างต้องสร้างได้ที่ระดับบนสุด (ซึ่งเข้ากันได้กับตัวเลือกระดับบนสุด) cquery จะแสดงผลลัพธ์การปิดชั่วคราวของเป้าหมายระดับบนสุดเหล่านี้

แม้ว่าจะสร้างเป้าหมายทั้งหมดในนิพจน์การค้นหาที่ระดับบนสุดได้ แต่ก็อาจมีประโยชน์ที่ไม่สร้าง เช่น การตั้งค่า --universe_scope อย่างชัดแจ้งอาจทำให้ไม่สามารถสร้างเป้าหมายหลายครั้งในการกำหนดค่าที่คุณไม่สนใจ นอกจากนี้ยังสามารถช่วยระบุเวอร์ชันการกำหนดค่าของเป้าหมายที่คุณต้องการ (เนื่องจากขณะนี้ไม่สามารถระบุรูปแบบการกำหนดค่านี้ได้อย่างสมบูรณ์) คุณควรตั้งค่าแฟล็กนี้หากนิพจน์การค้นหามีความซับซ้อนมากกว่า deps(//foo)

--implicit_deps (บูลีน, default=True)

การตั้งค่าแฟล็กนี้เป็น "เท็จ" จะกรองผลลัพธ์ทั้งหมดที่ไม่ได้กำหนดไว้อย่างชัดเจนในไฟล์ BUILD และตั้งค่าที่อื่นโดย Bazel แทน ซึ่งรวมถึงการกรอง Toolchain ที่แก้ไขแล้ว

--tool_deps (บูลีน, default=True)

การตั้งค่าแฟล็กนี้เป็น "เท็จ" จะกรองเป้าหมายที่กําหนดค่าไว้ทั้งหมดซึ่งเส้นทางจากเป้าหมายที่ค้นหาไปยังเป้าหมายดังกล่าวมีการข้ามการเปลี่ยนระหว่างการกําหนดค่าเป้าหมายและการกําหนดค่าที่ไม่ใช่เป้าหมาย หากเป้าหมายที่ค้นหาอยู่ในการกำหนดค่าเป้าหมาย การตั้งค่า --notool_deps จะส่งกลับเฉพาะเป้าหมายที่อยู่ในการกำหนดค่าเป้าหมายด้วยเท่านั้น หากเป้าหมายที่ค้นหาอยู่ในการกำหนดค่าที่ไม่ใช่เป้าหมาย การตั้งค่า --notool_deps จะส่งกลับเฉพาะเป้าหมายในการกำหนดค่าที่ไม่ใช่เป้าหมายด้วย โดยทั่วไปการตั้งค่านี้จะไม่ส่งผลต่อการกรอง เครื่องมือที่ได้รับการแก้ไข

--include_aspects (บูลีน, default=True)

มุมมองจะเพิ่มทรัพยากร Dependency เพิ่มเติมให้กับบิลด์ได้ โดยค่าเริ่มต้น cquery จะไม่ทำตามองค์ประกอบต่างๆ เนื่องจากทำให้กราฟที่ค้นหามีขนาดใหญ่ขึ้นซึ่งใช้หน่วยความจำมากขึ้น แต่การทำตามหลักเกณฑ์นี้จะให้ผลลัพธ์ ที่ถูกต้องมากขึ้น

หากคุณไม่กังวลเกี่ยวกับผลกระทบด้านความจำของข้อความค้นหาขนาดใหญ่ ให้เปิดใช้ค่าสถานะนี้โดยค่าเริ่มต้นใน bazelrc

หากค้นหาโดยปิดใช้ด้าน คุณจะพบปัญหาเมื่อเป้าหมาย X ล้มเหลวขณะสร้างเป้าหมาย Y แต่ cquery somepath(Y, X) และ cquery deps(Y) | grep 'X' ไม่แสดงผลลัพธ์เนื่องจากทรัพยากร Dependency เกิดขึ้นผ่านด้านหนึ่งๆ

รูปแบบเอาต์พุต

โดยค่าเริ่มต้น เอาต์พุต cquery จะแสดงรายการคู่ป้ายกำกับและการกำหนดค่าที่เรียงลำดับตามทรัพยากร และยังมีตัวเลือกอื่นๆ ในการแสดงผลลัพธ์เช่นกัน

การเปลี่ยนฉาก

--transitions=lite
--transitions=full

การเปลี่ยนการกำหนดค่าใช้ในการสร้างเป้าหมายภายใต้เป้าหมายระดับบนสุดในการกำหนดค่าที่แตกต่างจากเป้าหมายระดับบนสุด

ตัวอย่างเช่น เป้าหมายอาจกำหนดการเปลี่ยนเป็นการกำหนดค่าโฮสต์โดยอิงตามทรัพยากร Dependency ทั้งหมดในแอตทริบิวต์ tools ซึ่งเรียกว่าการเปลี่ยน แอตทริบิวต์ กฎยังสามารถทำให้เกิดการเปลี่ยนการกำหนดค่าของตัวเอง หรือที่เรียกว่าการเปลี่ยนคลาสของกฎ รูปแบบเอาต์พุตนี้จะให้ข้อมูลเกี่ยวกับการเปลี่ยนเหล่านี้ เช่น ประเภทการเปลี่ยนและผลที่มีต่อตัวเลือกบิลด์

รูปแบบเอาต์พุตนี้จะทริกเกอร์โดยแฟล็ก --transitions ซึ่งตั้งค่าเริ่มต้นเป็น NONE สามารถตั้งค่าเป็นโหมด FULL หรือ LITE โหมด FULL จะให้ข้อมูลเกี่ยวกับการเปลี่ยนคลาสของกฎและการเปลี่ยนแอตทริบิวต์ รวมถึงความแตกต่างโดยละเอียดของตัวเลือกก่อนและหลังการเปลี่ยน โหมด LITE จะส่งออกข้อมูลเดียวกันโดยไม่มีความแตกต่างของตัวเลือก

เอาต์พุตข้อความโปรโตคอล

--output=proto

ตัวเลือกนี้จะทำให้เป้าหมายที่ได้พิมพ์ออกมาในรูปแบบบัฟเฟอร์โปรโตคอลไบนารี ดูคำจำกัดความของบัฟเฟอร์โปรโตคอลได้ที่ src/main/protobuf/analysis.proto

CqueryResult คือข้อความระดับบนสุดที่มีผลลัพธ์ของ cquery โดยมีรายการข้อความ ConfiguredTarget และรายการข้อความ Configuration ConfiguredTarget แต่ละรายการจะมี configuration_id ที่มีค่าเท่ากับค่าของช่อง id จากข้อความ Configuration ที่เกี่ยวข้อง

--[no]proto:include_configurations

โดยค่าเริ่มต้น ผลลัพธ์ cquery จะแสดงข้อมูลการกำหนดค่าเป็นส่วนหนึ่งของเป้าหมายที่กำหนดค่าแต่ละรายการ หากคุณไม่ต้องการใช้ข้อมูลนี้และรับเอาต์พุตโปรโตที่มีการจัดรูปแบบเหมือนกับเอาต์พุตโปรโตของข้อความค้นหาทุกประการ ให้ตั้งค่าแฟล็กนี้เป็น false (เท็จ)

ดูเอกสารเกี่ยวกับเอาต์พุตโปรโตของคำค้นหาสำหรับตัวเลือกอื่นๆ ที่เกี่ยวข้องกับเอาต์พุตโปรโต

เอาต์พุตกราฟ

--output=graph

ตัวเลือกนี้จะสร้างเอาต์พุตเป็นไฟล์ .dot ที่ใช้ร่วมกับ Graphviz ได้ โปรดดูรายละเอียดในเอกสารประกอบเกี่ยวกับเอาต์พุตกราฟของ query cquery ยังรองรับ --graph:node_limit และ --graph:factored ด้วย

เอาต์พุตไฟล์

--output=files

ตัวเลือกนี้จะพิมพ์รายการไฟล์เอาต์พุตที่เป้าหมายแต่ละรายการสร้างขึ้นที่ตรงกับการค้นหาซึ่งคล้ายกับรายการที่พิมพ์ไว้ท้ายคำขอ bazel build เอาต์พุตจะมีเฉพาะไฟล์ที่โฆษณาในกลุ่มเอาต์พุตที่ขอตามที่กำหนดโดยแฟล็ก --output_groups แต่ไม่รวมถึงไฟล์ต้นฉบับ

การกำหนดรูปแบบเอาต์พุตโดยใช้ Starlark

--output=starlark

รูปแบบเอาต์พุตนี้เรียกใช้ฟังก์ชัน Starlark สำหรับแต่ละเป้าหมายที่กำหนดค่าไว้ในผลลัพธ์ข้อความค้นหา และพิมพ์ค่าที่ส่งคืนโดยการเรียก แฟล็ก --starlark:file ระบุตำแหน่งของไฟล์ Starlark ที่กำหนดฟังก์ชันที่ชื่อว่า format ด้วยพารามิเตอร์เดียว นั่นคือ target ระบบจะเรียกใช้ฟังก์ชันนี้สำหรับเป้าหมายแต่ละรายการในผลการค้นหา หรือเพื่อความสะดวก คุณอาจระบุเฉพาะเนื้อหาของฟังก์ชันที่ประกาศเป็น def format(target): return expr โดยใช้แฟล็ก --starlark:expr

ภาษา "cquery" แบบ Starlark

สภาพแวดล้อมการค้นหา Starlark แตกต่างจากไฟล์ BUILD หรือ .bzl ซึ่งรวมถึงค่าคงที่และฟังก์ชันในตัวของ Starlark หลักทั้งหมด รวมถึงค่าเฉพาะคำค้นหาที่อธิบายไว้ด้านล่าง แต่ไม่ใช่ (ตัวอย่างเช่น) glob, native หรือ rule และไม่รองรับคำสั่งการโหลด

build_options(target)

build_options(target) จะแสดงแผนที่ซึ่งมีคีย์เป็นตัวระบุตัวเลือกการสร้าง (ดูการกำหนดค่า) และคีย์ที่มีค่าเป็น Starlark ตัวเลือกบิวด์ที่ค่าที่ไม่ใช่ค่า Starlark ถูกกฎหมายจะไม่รวมอยู่ในแผนที่นี้

หากเป้าหมายเป็นไฟล์อินพุต build_options(target) จะแสดงผลเป็น "ไม่มี" เนื่องจากเป้าหมายไฟล์อินพุตมีการกำหนดค่าเป็นค่าว่าง

ผู้ให้บริการ(เป้าหมาย)

providers(target) จะแสดงผลแผนที่ซึ่งมีคีย์เป็นชื่อของ providers (เช่น "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()]"

พิมพ์ค่าของตัวเลือกบรรทัดคำสั่ง --javacopt เมื่อสร้าง //foo

  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 และ query ส่งเสริมกันและกันและเก่งในเรื่องเฉพาะกลุ่มที่แตกต่างกัน พิจารณาสิ่งต่อไปนี้เพื่อตัดสินใจว่าตัวเลือกใดเหมาะกับคุณ

  • cquery จะติดตามกิ่งก้าน select() ที่เจาะจงเพื่อสร้างรูปแบบกราฟที่ถูกต้องที่คุณสร้างขึ้น query ไม่ทราบว่าบิลด์เลือก Branch ใด ดังนั้นต้องใกล้เคียงมากด้วยการรวมสาขาทั้งหมด
  • ความแม่นยำของ cquery จำเป็นต้องสร้างกราฟให้มากกว่า query โดยเฉพาะอย่างยิ่ง cquery จะประเมินเป้าหมายที่กําหนดค่าไว้ ขณะที่ query จะประเมินเฉพาะเป้าหมายเท่านั้น ซึ่งจะใช้เวลานานขึ้นและใช้หน่วยความจำมากขึ้น
  • การตีความภาษาในการค้นหาของ cquery ทำให้เกิดความกำกวมที่ query หลีกเลี่ยง เช่น หากมี "//foo" อยู่ในการกำหนดค่า 2 รายการ cquery "deps(//foo)" ควรใช้การกำหนดค่าใด ฟังก์ชัน [config](#config) สามารถช่วยในเรื่องนี้ได้
  • เนื่องจากเป็นเครื่องมือที่ใหม่กว่า cquery จึงขาดการสนับสนุนการใช้งานบางกรณี ดูรายละเอียดได้ที่ปัญหาที่ทราบ

ปัญหาที่ทราบ

เป้าหมายทั้งหมดที่ cquery "สร้าง" ต้องมีการกำหนดค่าเหมือนกัน

ก่อนประเมินคำค้นหา cquery จะทริกเกอร์บิวด์ก่อนจุดที่การทำงานของบิลด์จะทำงาน โดยค่าเริ่มต้น ระบบจะเลือกเป้าหมายที่ "builds" มาจากป้ายกำกับทั้งหมดที่ปรากฏในนิพจน์การค้นหา (ซึ่งลบล้างได้ด้วย --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 "+" -))"