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

ไวยากรณ์พื้นฐาน

การเรียกใช้ cquery แบบง่ายจะมีลักษณะดังนี้

bazel cquery "function(//target)"

นิพจน์การค้นหา "function(//target)" ประกอบด้วยข้อมูลต่อไปนี้

  • function(...) คือฟังก์ชันที่จะเรียกใช้ในเป้าหมาย cquery รองรับฟังก์ชันส่วนใหญ่ ของ query's functions รวมถึงฟังก์ชันใหม่ๆ อีก 2-3 ฟังก์ชัน
  • //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's target pattern documentation

ฟังก์ชัน

จากชุดฟังก์ชัน ที่ query รองรับ cquery รองรับฟังก์ชันทั้งหมด ยกเว้น allrdeps, buildfiles, rbuildfiles, siblings, tests และ visible

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

config

expr ::= config(expr, word)

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

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

การใช้ตัวเลือก 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"],
)

Genrule กำหนดค่าเครื่องมือในการกำหนดค่า exec ดังนั้นการค้นหาต่อไปนี้จะสร้างเอาต์พุตต่อไปนี้

การค้นหา เป้าหมายที่สร้างขึ้น เอาต์พุต
bazel cquery "//x:tool" //x:tool //x:tool(targetconfig)
bazel cquery "//x:tool" --universe_scope="//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' จะละเว้น Y หาก X พึ่งพา Y ผ่านแง่มุมต่างๆ เท่านั้น

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

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

ทรานซิชัน

--transitions=lite
--transitions=full

ทรานซิชันการกำหนดค่า ใช้เพื่อสร้างเป้าหมายที่อยู่ใต้เป้าหมายระดับบนสุดในการกำหนดค่าที่แตกต่างจากเป้าหมายระดับบนสุด

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

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

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

--output=proto

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

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

--[no]proto:include_configurations

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

ดูตัวเลือกเพิ่มเติมที่เกี่ยวข้องกับเอาต์พุตโปรโตได้ในเอกสารประกอบเกี่ยวกับเอาต์พุตโปรโตของ query's

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

--output=graph

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

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

--output=files

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

เส้นทางทั้งหมดที่รูปแบบเอาต์พุตนี้ปล่อยออกมาจะสัมพันธ์กับ execroot ซึ่งรับได้ ผ่าน bazel info execution_root หากมี symlink ความสะดวก bazel-out เส้นทางไปยังไฟล์ในที่เก็บหลักก็จะสัมพันธ์กับไดเรกทอรีพื้นที่ทำงานด้วย

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

--output=starlark

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

Dialect Starlark ของ 'cquery'

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

build_options(target)

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

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

providers(target)

providers(target) จะแสดงผลแผนที่ที่มีคีย์เป็นชื่อของ ผู้ให้บริการ (เช่น "DefaultInfo") และค่าเป็นค่า Starlark ระบบจะละเว้นผู้ให้บริการที่มีค่าไม่ใช่ค่า Starlark ที่ถูกต้องจากแผนที่นี้

ตัวอย่าง

พิมพ์รายการชื่อฐานของไฟล์ทั้งหมดที่สร้างโดย //foo โดยคั่นด้วยช่องว่าง

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

พิมพ์รายการเส้นทางของไฟล์ทั้งหมดที่สร้างโดยเป้าหมาย กฎ ใน //bar และแพ็กเกจย่อย โดยคั่นด้วยช่องว่าง

  bazel cquery 'kind(rule, //bar/...)' --output=starlark \
    --starlark:expr="' '.join([f.path for f in providers(target)['DefaultInfo'].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(providers(target)["DefaultInfo"].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 จะติดตาม Branch select() ที่เฉพาะเจาะจงเพื่อสร้างกราฟที่แน่นอนที่คุณสร้าง query ไม่ทราบว่าบิลด์เลือกกิ่งก้านใด จึงประมาณค่ามากเกินไปโดยรวมกิ่งก้านทั้งหมด
  • ความแม่นยำของ cquery's ต้องสร้างกราฟมากกว่า query โดยเฉพาะอย่างยิ่ง cquery จะประเมิน เป้าหมายที่กำหนดค่าไว้ ขณะที่ query จะประเมินเฉพาะ เป้าหมาย ซึ่งใช้เวลามากขึ้นและใช้หน่วยความจำมากขึ้น
  • การตีความ ของภาษาการค้นหาของ cquery ทำให้เกิดความกำกวม ที่ query หลีกเลี่ยง ตัวอย่างเช่น หาก "//foo" มีอยู่ในการกำหนดค่า 2 รายการ ควรใช้รายการใด cquery "deps(//foo)" ฟังก์ชัน config ช่วยในเรื่องนี้ได้

เอาต์พุตที่ไม่แน่นอน

cquery จะไม่ล้างกราฟบิลด์จากคำสั่งก่อนหน้าโดยอัตโนมัติ จึงมีแนวโน้มที่จะรับผลลัพธ์จากการค้นหาที่ผ่านมา

ตัวอย่างเช่น genrule จะกำหนดทรานซิชัน exec ในแอตทริบิวต์ tools - นั่นคือ กำหนดค่าเครื่องมือในการกำหนดค่า exec

คุณจะเห็นผลกระทบที่หลงเหลืออยู่ของการเปลี่ยนผ่านนั้นด้านล่าง

$ cat > foo/BUILD <<

พฤติกรรมนี้อาจเป็นที่ต้องการหรือไม่ก็ได้ ขึ้นอยู่กับสิ่งที่คุณพยายามประเมิน

หากต้องการปิดใช้ ให้เรียกใช้ blaze clean ก่อน cquery เพื่อให้แน่ใจว่ากราฟการวิเคราะห์ใหม่

การแก้ปัญหา

รูปแบบเป้าหมายแบบเรียกซ้ำ (/...)

หากคุณพบข้อความต่อไปนี้

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