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
รวมถึงฟังก์ชันใหม่ๆ อีก 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
ฟังก์ชัน
ในชุดฟังก์ชัน
ที่ query
รองรับ cquery
รองรับฟังก์ชันทั้งหมด ยกเว้น
allrdeps
buildfiles
rbuildfiles
siblings
tests
และ
visible
cquery
ยังมีฟังก์ชันใหม่ต่อไปนี้ด้วย
การกำหนดค่า
expr ::= config(expr, word)
ตัวดำเนินการ config
พยายามค้นหาเป้าหมายที่กำหนดค่าไว้สำหรับ
ป้ายกำกับที่ระบุโดยอาร์กิวเมนต์แรกและการกำหนดค่าที่ระบุโดย
อาร์กิวเมนต์ที่สอง
ค่าที่ใช้ได้สำหรับอาร์กิวเมนต์ที่ 2 คือ 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
ทำงานผ่านการบิลด์ Bazel ปกติ จึงรับช่วงชุดตัวเลือกที่ใช้ได้ในระหว่างการบิลด์
การใช้ตัวเลือก cquery
--universe_scope
(รายการที่คั่นด้วยคอมมา)
บ่อยครั้งที่การขึ้นต่อกันของเป้าหมายที่กำหนดค่าจะผ่านทรานซิชัน ซึ่งทำให้การกำหนดค่าแตกต่างจากการขึ้นต่อกัน แฟล็กนี้ ช่วยให้คุณค้นหาเป้าหมายได้ราวกับว่าสร้างขึ้นเป็นทรัพยากร Dependency หรือทรัพยากร Dependency แบบทรานซิทีฟ ของเป้าหมายอื่น เช่น
# x/BUILD genrule( name = "my_gen", srcs = ["x.in"], outs = ["x.cc"], cmd = "$(locations :tool) $< >$@", tools = [":tool"], ) cc_binary( name = "tool", srcs = ["tool.cpp"], )
Genrules กำหนดค่าเครื่องมือใน exec configuration เพื่อให้การค้นหาต่อไปนี้สร้างเอาต์พุตต่อไปนี้
การค้นหา | สร้างเป้าหมายแล้ว | เอาต์พุต |
---|---|---|
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
จะแสดงผลลัพธ์ใน Closure แบบทรานซิทีฟของเป้าหมายระดับบนสุดเหล่านี้
แม้ว่าจะสร้างเป้าหมายทั้งหมดในนิพจน์การค้นหาที่ระดับบนสุดได้
แต่การไม่ทำเช่นนั้นอาจเป็นประโยชน์ ตัวอย่างเช่น การตั้งค่า --universe_scope
อย่างชัดเจนอาจช่วยป้องกันไม่ให้สร้างเป้าหมายหลายครั้งในการกำหนดค่าที่คุณไม่สนใจ
นอกจากนี้ยังช่วยระบุเวอร์ชันการกำหนดค่าของเป้าหมายที่คุณกำลังมองหาได้ด้วย (เนื่องจากปัจจุบันยังไม่สามารถระบุได้อย่างเต็มที่ด้วยวิธีอื่น) คุณควรตั้งค่าสถานะนี้
หากนิพจน์การค้นหาซับซ้อนกว่า deps(//foo)
--implicit_deps
(บูลีน ค่าเริ่มต้นคือ True)
การตั้งค่าแฟล็กนี้เป็น false จะกรองผลลัพธ์ทั้งหมดที่ไม่ได้ตั้งค่าอย่างชัดเจนใน ไฟล์ BUILD และ Bazel จะตั้งค่าไว้ที่อื่นแทน ซึ่งรวมถึงการกรองเครื่องมือที่แก้ไขแล้ว ด้วย
--tool_deps
(บูลีน ค่าเริ่มต้นคือ True)
การตั้งค่าสถานะนี้เป็น "เท็จ" จะกรองเป้าหมายที่กำหนดค่าทั้งหมดซึ่งเส้นทางจากเป้าหมายที่ค้นหาไปยังเป้าหมายเหล่านั้นข้ามการเปลี่ยนผ่านระหว่างการกำหนดค่าเป้าหมายกับการกำหนดค่าที่ไม่ใช่เป้าหมาย
หากเป้าหมายที่ค้นหาอยู่ในการกำหนดค่าเป้าหมาย การตั้งค่า --notool_deps
จะ
แสดงเฉพาะเป้าหมายที่อยู่ในการกำหนดค่าเป้าหมายด้วย หากเป้าหมายที่ค้นหาอยู่ในการกำหนดค่าที่ไม่ใช่เป้าหมาย การตั้งค่า --notool_deps
จะแสดงเฉพาะเป้าหมายที่อยู่ในการกำหนดค่าที่ไม่ใช่เป้าหมายด้วย โดยทั่วไปแล้ว การตั้งค่านี้จะไม่มีผลต่อการกรอง
ของ Toolchain ที่แก้ไขแล้ว
--include_aspects
(บูลีน ค่าเริ่มต้นคือ True)
รวมการพึ่งพาที่เพิ่มโดยแง่มุม
หากปิดใช้ฟีเจอร์นี้ cquery somepath(X, Y)
และ
cquery deps(X) | grep 'Y'
จะละเว้น Y หาก X ขึ้นอยู่กับ Y ผ่านแง่มุมเท่านั้น
รูปแบบเอาต์พุต
โดยค่าเริ่มต้น cquery จะแสดงผลลัพธ์ในรายการป้ายกำกับและการกำหนดค่าที่จัดเรียงตามการอ้างอิง นอกจากนี้ ยังมีตัวเลือกอื่นๆ ในการแสดงผลลัพธ์ด้วย
ทรานซิชัน
--transitions=lite --transitions=full
ทรานซิชันการกำหนดค่า ใช้เพื่อสร้างเป้าหมายภายใต้เป้าหมายระดับบนสุดในการกำหนดค่าที่แตกต่างกัน กว่าเป้าหมายระดับบนสุด
เช่น เป้าหมายอาจกำหนดให้เปลี่ยนไปใช้การกำหนดค่า exec ในการขึ้นต่อกันทั้งหมดในแอตทริบิวต์ tools
ซึ่งเรียกว่าการเปลี่ยนแอตทริบิวต์ นอกจากนี้ กฎยังกำหนดการเปลี่ยนสถานะในการกำหนดค่าของตัวเองได้ด้วย
ซึ่งเรียกว่าการเปลี่ยนสถานะของคลาสกฎ รูปแบบเอาต์พุตนี้จะแสดงข้อมูลเกี่ยวกับการเปลี่ยนผ่านเหล่านี้ เช่น ประเภทของการเปลี่ยนผ่านและผลกระทบที่มีต่อตัวเลือกบิลด์
รูปแบบเอาต์พุตนี้จะทริกเกอร์โดยแฟล็ก --transitions
ซึ่งตั้งค่าเป็น NONE
โดยค่าเริ่มต้น
โดยตั้งค่าเป็นโหมด FULL
หรือ LITE
ได้ โหมด FULL
จะแสดงข้อมูลเกี่ยวกับการเปลี่ยนคลาสของกฎและการเปลี่ยนแอตทริบิวต์ รวมถึงส่วนต่างโดยละเอียดของตัวเลือกก่อนและหลังการเปลี่ยน LITE
mode
จะแสดงข้อมูลเดียวกันโดยไม่มีความแตกต่างของตัวเลือก
เอาต์พุตข้อความโปรโตคอล
--output=proto
ตัวเลือกนี้จะทำให้มีการพิมพ์เป้าหมายที่ได้ในรูปแบบบัฟเฟอร์โปรโตคอลไบนารี ดูคำจำกัดความของบัฟเฟอร์โปรโตคอลได้ที่ src/main/protobuf/analysis_v2.proto
CqueryResult
คือข้อความระดับบนสุดที่มีผลลัพธ์ของ cquery โดยมีรายการConfiguredTarget
ข้อความและรายการConfiguration
ข้อความ ConfiguredTarget
แต่ละรายการมี configuration_id
ซึ่งมีค่าเท่ากับค่าของฟิลด์ id
จากข้อความ Configuration
ที่เกี่ยวข้อง
--[no]proto:include_configurations
โดยค่าเริ่มต้น ผลลัพธ์ของ cquery จะแสดงข้อมูลการกำหนดค่าเป็นส่วนหนึ่งของเป้าหมายที่กำหนดค่าแต่ละรายการ หากต้องการละเว้นข้อมูลนี้และรับเอาต์พุต Proto ที่มีการจัดรูปแบบเหมือนกับเอาต์พุต Proto ของการค้นหาทุกประการ ให้ตั้งค่าสถานะนี้เป็น false
ดูตัวเลือกเพิ่มเติมที่เกี่ยวข้องกับเอาต์พุต Proto ได้ในเอกสารประกอบเกี่ยวกับเอาต์พุต Proto ของการค้นหา
เอาต์พุตกราฟ
--output=graph
ตัวเลือกนี้จะสร้างเอาต์พุตเป็นไฟล์ .dot ที่เข้ากันได้กับ Graphviz ดูรายละเอียดได้ในquery
เอกสารประกอบเกี่ยวกับเอาต์พุตกราฟ cquery
ยังรองรับ --graph:node_limit
และ
--graph:factored
ด้วย
เอาต์พุตไฟล์
--output=files
ตัวเลือกนี้จะพิมพ์รายการไฟล์เอาต์พุตที่สร้างขึ้นโดยแต่ละเป้าหมายที่ตรงกัน
ตามคำค้นหาที่คล้ายกับรายการที่พิมพ์เมื่อสิ้นสุดการเรียกใช้ bazel build
เอาต์พุตจะมีเฉพาะไฟล์ที่โฆษณาในกลุ่มเอาต์พุตที่ขอตามที่กำหนดโดยแฟล็ก --output_groups
แต่จะรวมไฟล์ต้นฉบับ
เส้นทางทั้งหมดที่รูปแบบเอาต์พุตนี้ปล่อยออกมาจะสัมพันธ์กับ
execroot ซึ่งรับได้
ผ่าน bazel info execution_root
หากมี bazel-out
Convenience Symlink
เส้นทางไปยังไฟล์ในที่เก็บหลักจะได้รับการแก้ไขโดยอิงตามไดเรกทอรีพื้นที่ทำงานด้วย
การกำหนดรูปแบบเอาต์พุตโดยใช้ Starlark
--output=starlark
รูปแบบเอาต์พุตนี้จะเรียกใช้ฟังก์ชัน Starlark
สำหรับแต่ละเป้าหมายที่กำหนดค่าไว้ในผลการค้นหา และพิมพ์ค่า
ที่เรียกใช้ แฟล็ก --starlark:file
ระบุตำแหน่งของไฟล์ Starlark ที่กำหนดฟังก์ชันชื่อ format
ที่มีพารามิเตอร์เดียว target
ฟังก์ชันนี้จะเรียกใช้สำหรับ Target แต่ละรายการ
ในผลการค้นหา หรือคุณจะระบุเฉพาะเนื้อหาของฟังก์ชันที่ประกาศเป็น def format(target): return expr
โดยใช้แฟล็ก --starlark:expr
เพื่อความสะดวกก็ได้
ภาษา Starlark ของ "cquery"
สภาพแวดล้อม Starlark ของ cquery แตกต่างจากไฟล์ BUILD หรือ .bzl ซึ่งรวมถึงค่าคงที่และฟังก์ชันในตัวของ Starlark หลักทั้งหมด
รวมถึงฟังก์ชันเฉพาะ cquery บางรายการที่อธิบายไว้ด้านล่าง แต่ไม่รวม (เช่น) glob
, native
หรือ rule
และไม่รองรับคำสั่ง load
build_options(target)
build_options(target)
จะแสดงผลแมปที่มีคีย์เป็นตัวระบุตัวเลือกการสร้าง (ดูการกำหนดค่า)
และมีค่าเป็นค่า Starlark ระบบจะละเว้นตัวเลือกบิลด์ที่มีค่าไม่ใช่ค่า Starlark ที่ถูกต้องตามกฎหมายออกจากแผนที่นี้
หากเป้าหมายเป็นไฟล์อินพุต build_options(target)
จะแสดงผลเป็น None เนื่องจากเป้าหมายไฟล์อินพุต
มีการกำหนดค่าเป็น Null
ผู้ให้บริการ(เป้าหมาย)
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 เทียบกับ query
cquery
และ query
ช่วยเสริมซึ่งกันและกันและโดดเด่นใน
กลุ่มเฉพาะที่แตกต่างกัน โปรดพิจารณาสิ่งต่อไปนี้เพื่อตัดสินใจว่าตัวเลือกใดเหมาะกับคุณ
cquery
จะติดตามกิ่งก้านselect()
ที่เฉพาะเจาะจงเพื่อ สร้างโมเดลกราฟที่คุณสร้างขึ้นquery
ไม่ทราบว่าบิลด์เลือกสาขาใด จึงประมาณค่าสูงเกินจริงโดยรวมทุกสาขา- ความแม่นยำของ
cquery
ต้องสร้างกราฟมากกว่าquery
กล่าวโดยเจาะจงคือcquery
จะประเมินเป้าหมายที่กำหนดค่า ขณะที่query
จะประเมินเป้าหมายเท่านั้น ซึ่งจะใช้เวลานานขึ้นและใช้หน่วยความจำมากขึ้น cquery
การตีความภาษาการค้นหาของ จะทำให้เกิดความกำกวม ซึ่งquery
หลีกเลี่ยง เช่น หาก"//foo"
มีอยู่ในการกำหนดค่า 2 รายการ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
จะใช้การเปลี่ยน exec กับแอตทริบิวต์ tools
ซึ่งหมายความว่ากำหนดค่าเครื่องมือในการกำหนดค่า 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=<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/...
ในขอบเขตของ Universe อย่างชัดเจน
$ 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 "+" -))"