คู่มือการค้นหา

รายงานปัญหา ดูแหล่งที่มา Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

หน้านี้จะอธิบายวิธีเริ่มต้นใช้งานภาษาการค้นหาของ Bazel เพื่อติดตาม การอ้างอิงในโค้ด

ดูรายละเอียดภาษาและ--outputรายละเอียดของแฟล็กได้ใน คู่มืออ้างอิง การอ้างอิงการค้นหา Bazel และการอ้างอิง cquery ของ Bazel คุณขอรับความช่วยเหลือได้โดย พิมพ์ bazel help query หรือ bazel help cquery ใน บรรทัดคำสั่ง

หากต้องการเรียกใช้การค้นหาโดยไม่สนใจข้อผิดพลาด เช่น เป้าหมายที่ขาดหายไป ให้ใช้แฟล็ก --keep_going

การค้นหาทรัพยากร Dependency ของกฎ

หากต้องการดูการขึ้นต่อกันของ //foo ให้ใช้ฟังก์ชัน deps ในการค้นหา Bazel ดังนี้

$ bazel query "deps(//foo)"
//foo:foo
//foo:foo-dep
...

นี่คือชุดเป้าหมายทั้งหมดที่จำเป็นต่อการสร้าง //foo

การติดตามห่วงโซ่การอ้างอิงระหว่างแพ็กเกจ 2 รายการ

ไลบรารี //third_party/zlib:zlibonly ไม่อยู่ในไฟล์ BUILD สำหรับ //foo แต่เป็นทรัพยากร Dependency โดยอ้อม เราจะติดตามเส้นทางการอ้างอิงนี้ได้อย่างไร ฟังก์ชันที่มีประโยชน์ 2 รายการในที่นี้ ได้แก่ allpaths และ somepath นอกจากนี้ คุณยังอาจต้องการยกเว้น การขึ้นต่อกันของเครื่องมือด้วย --notool_deps หากคุณสนใจเฉพาะ สิ่งที่รวมอยู่ในอาร์ติแฟกต์ที่คุณสร้างขึ้น และไม่ใช่ทุกงานที่เป็นไปได้

หากต้องการแสดงภาพกราฟของการขึ้นต่อกันทั้งหมด ให้ส่งเอาต์พุตการค้นหาของ Bazel ผ่าน เครื่องมือบรรทัดคำสั่ง dot

$ bazel query "allpaths(//foo, third_party/...)" --notool_deps --output graph | dot -Tsvg > /tmp/deps.svg

เมื่อกราฟการขึ้นต่อกันมีขนาดใหญ่และซับซ้อน คุณอาจเริ่มจากเส้นทางเดียวได้

$ bazel query "somepath(//foo:foo, third_party/zlib:zlibonly)"
//foo:foo
//translations/tools:translator
//translations/base:base
//third_party/py/MySQL:MySQL
//third_party/py/MySQL:_MySQL.so
//third_party/mysql:mysql
//third_party/zlib:zlibonly

หากไม่ได้ระบุ --output graph ด้วย allpaths คุณจะได้รับรายการกราฟการอ้างอิงแบบแบน

$ bazel query "allpaths(//foo, third_party/...)"
  ...many errors detected in BUILD files...
//foo:foo
//translations/tools:translator
//translations/tools:aggregator
//translations/base:base
//tools/pkg:pex
//tools/pkg:pex_phase_one
//tools/pkg:pex_lib
//third_party/python:python_lib
//translations/tools:messages
//third_party/py/xml:xml
//third_party/py/xml:utils/boolean.so
//third_party/py/xml:parsers/sgmlop.so
//third_party/py/xml:parsers/pyexpat.so
//third_party/py/MySQL:MySQL
//third_party/py/MySQL:_MySQL.so
//third_party/mysql:mysql
//third_party/openssl:openssl
//third_party/zlib:zlibonly
//third_party/zlib:zlibonly_v1_2_3
//third_party/python:headers
//third_party/openssl:crypto

หมายเหตุ: การอ้างอิงโดยนัย

ไฟล์ BUILD สำหรับ //foo never references //translations/tools:aggregator แล้วการอ้างอิงโดยตรงอยู่ที่ไหน

กฎบางอย่างมีการอ้างอิงโดยนัยกับไลบรารีหรือเครื่องมือเพิ่มเติม ตัวอย่างเช่น หากต้องการสร้างgenproto คุณต้องสร้างคอมไพเลอร์โปรโตคอลก่อน ดังนั้นกฎ genproto ทุกข้อจึงมีทรัพยากร Dependency โดยนัยในคอมไพเลอร์โปรโตคอล แม้ว่าจะไม่ได้ระบุการขึ้นต่อกันเหล่านี้ในไฟล์บิลด์ แต่เครื่องมือบิลด์จะเพิ่มให้ ชุดการอ้างอิงโดยนัยทั้งหมด ยังไม่มีเอกสารประกอบในขณะนี้ การใช้ --noimplicit_deps จะช่วยให้คุณกรอง การอ้างอิงเหล่านี้ออกจากผลการค้นหาได้ สำหรับ cquery จะรวมถึง Toolchain ที่แก้ไขแล้ว

ทรัพยากร Dependency แบบย้อนกลับ

คุณอาจต้องการทราบชุดเป้าหมายที่ขึ้นอยู่กับเป้าหมายบางอย่าง เช่น หากคุณจะเปลี่ยนโค้ดบางส่วน คุณอาจต้องการทราบว่าโค้ดอื่นๆ ที่คุณกำลังจะทำให้ใช้งานไม่ได้คืออะไร คุณใช้ rdeps(u, x) เพื่อค้นหาการอ้างอิงย้อนกลับของเป้าหมายใน x ภายใน Transitive Closure ของ u ได้

Sky Query ของ Bazel รองรับฟังก์ชัน allrdeps ซึ่งช่วยให้คุณค้นหาการอ้างอิงย้อนกลับ ในจักรวาลที่คุณระบุได้

การใช้งานอื่นๆ

คุณใช้ bazel query เพื่อวิเคราะห์ความสัมพันธ์ของการอ้างอิงหลายรายการได้

สิ่งที่ ... มีอยู่

มีแพ็กเกจใดบ้างที่อยู่ภายใต้ foo

bazel query 'foo/...' --output package

foo แพ็กเกจมีกฎอะไรบ้าง

bazel query 'kind(rule, foo:*)' --output label_kind

กฎในแพ็กเกจ foo สร้างไฟล์ใด

bazel query 'kind("generated file", //foo:*)'

มาโคร Starlark foo สร้างเป้าหมายใด

bazel query 'attr(generator_function, foo, //path/to/search/...)'

ต้องใช้ไฟล์ BUILD ชุดใดในการสร้าง //foo

bazel query 'buildfiles(deps(//foo))' | cut -f1 -d:

test_suite ขยายเป็นการทดสอบแต่ละรายการใด

bazel query 'tests(//foo:smoke_tests)'

การทดสอบใดบ้างที่เป็นการทดสอบ C++

bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'

มีอะไรบ้าง ปานกลาง ใหญ่

bazel query 'attr(size, small, tests(//foo:smoke_tests))'

bazel query 'attr(size, medium, tests(//foo:smoke_tests))'

bazel query 'attr(size, large, tests(//foo:smoke_tests))'

การทดสอบที่อยู่ใต้ foo ซึ่งตรงกับรูปแบบคืออะไร

bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))'

รูปแบบเป็นนิพจน์ทั่วไปและใช้กับชื่อเต็มของกฎ ซึ่งคล้ายกับการทำ

bazel query 'kind(".*_test rule", //foo/...)' | grep -E 'pa?t'

แพ็กเกจใดที่มีไฟล์ path/to/file/bar.java

 bazel query path/to/file/bar.java --output=package

ป้ายกำกับการสร้างสำหรับ path/to/file/bar.java? คืออะไร

bazel query path/to/file/bar.java

เป้าหมายกฎใดที่มีไฟล์ path/to/file/bar.java เป็นแหล่งที่มา

fullname=$(bazel query path/to/file/bar.java)
bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"

มีการขึ้นต่อกันของแพ็กเกจใดบ้าง ...

foo ขึ้นอยู่กับแพ็กเกจใด (ฉันต้องดูอะไรบ้างเพื่อสร้าง foo)

bazel query 'buildfiles(deps(//foo:foo))' --output package

foo ทรีขึ้นอยู่กับแพ็กเกจใดบ้าง ยกเว้น foo/contrib

bazel query 'deps(foo/... except foo/contrib/...)' --output package

การขึ้นต่อกันของกฎมีอะไรบ้าง ...

กฎ genproto ใดที่ bar ขึ้นอยู่กับ

bazel query 'kind(genproto, deps(bar/...))'

ค้นหานิยามของไลบรารี JNI (C++) บางรายการที่กฎไบนารี Java ในทรีของเซอร์블릿ขึ้นต่อกันแบบทรานซิทีฟ

bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
...ตอนนี้ให้ค้นหานิยามของไบนารี Java ทั้งหมดที่ขึ้นอยู่กับไบนารีเหล่านั้น
bazel query 'let jbs = kind(java_binary, //java/com/example/frontend/...) in
  let cls = kind(cc_.*library, deps($jbs)) in
    $jbs intersect allpaths($jbs, $cls)'

มีการขึ้นต่อกันของไฟล์ใดบ้าง ...

ต้องใช้ไฟล์ต้นฉบับ Java ใดบ้างในการสร้าง foo

ไฟล์ต้นฉบับ:

bazel query 'kind("source file", deps(//path/to/target/foo/...))' | grep java$

ไฟล์ที่สร้าง

bazel query 'kind("generated file", deps(//path/to/target/foo/...))' | grep java$

ชุดไฟล์ต้นฉบับ Java ทั้งหมดที่จำเป็นต่อการสร้างการทดสอบของ QUX คืออะไร

ไฟล์ต้นฉบับ:

bazel query 'kind("source file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$

ไฟล์ที่สร้าง

bazel query 'kind("generated file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$

ความแตกต่างของทรัพยากร Dependency ระหว่าง X กับ Y มีอะไรบ้าง ...

//foo ขึ้นอยู่กับเป้าหมายใดที่ //foo:foolib ไม่ได้ขึ้นอยู่ด้วย

bazel query 'deps(//foo) except deps(//foo:foolib)'

ไลบรารี C++ ใดบ้างที่การทดสอบ foo ต้องใช้ แต่ไบนารีเวอร์ชันที่ใช้งานจริง //foo ไม่ต้องใช้

bazel query 'kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo))'

เหตุใดจึงมีการขึ้นต่อกันนี้ ...

ทำไม bar จึงต้องใช้ groups2

bazel query 'somepath(bar/...,groups2/...:*)'

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

แสดงเส้นทางจาก docker/updater:updater_systest (py_test) ไปยัง cc_library ที่ขึ้นอยู่กับ docker/updater:updater_systest

bazel query 'let cc = kind(cc_library, deps(docker/updater:updater_systest)) in
  somepath(docker/updater:updater_systest, $cc)'

เหตุใดไลบรารี //photos/frontend:lib จึงขึ้นอยู่กับไลบรารี //third_party/jpeglib และ //third_party/jpeg ที่เป็นไลบรารีเดียวกันแต่มี 2 รูปแบบ

การค้นหานี้สรุปได้ว่า "แสดงกราฟย่อยของ //photos/frontend:lib ที่ ขึ้นอยู่กับทั้ง 2 ไลบรารี" เมื่อแสดงตามลำดับโทโพโลยี องค์ประกอบสุดท้าย ของผลลัพธ์คือสาเหตุที่น่าจะเป็นมากที่สุด

bazel query 'allpaths(//photos/frontend:lib, //third_party/jpeglib)
                intersect
               allpaths(//photos/frontend:lib, //third_party/jpeg)'
//photos/frontend:lib
//photos/frontend:lib_impl
//photos/frontend:lib_dispatcher
//photos/frontend:icons
//photos/frontend/modules/gadgets:gadget_icon
//photos/thumbnailer:thumbnail_lib
//third_party/jpeg/img:renderer

สิ่งที่ขึ้นอยู่กับ ...

กฎใดภายใต้แถบขึ้นอยู่กับ Y

bazel query 'bar/... intersect allpaths(bar/..., Y)'

เป้าหมายใดที่ขึ้นอยู่กับ T โดยตรงในแพ็กเกจของ T

bazel query 'same_pkg_direct_rdeps(T)'

ฉันจะยกเลิกการขึ้นต่อกันได้อย่างไร ...

ฉันต้องยกเลิกเส้นทางการอ้างอิงใดบ้างเพื่อให้ bar ไม่ต้องอ้างอิง X อีกต่อไป

วิธีส่งออกกราฟเป็นไฟล์ svg

bazel query 'allpaths(bar/...,X)' --output graph | dot -Tsvg > /tmp/dep.svg

อื่นๆ

//foo-testsการสร้างมีขั้นตอนตามลำดับกี่ขั้นตอน

ปัจจุบันภาษาการค้นหายังไม่สามารถแสดงเส้นทางที่ยาวที่สุดจาก x ไปยัง y ได้ แต่สามารถค้นหาโหนดที่ไกลที่สุด (หรือโหนด) จากจุดเริ่มต้น หรือแสดงความยาวของเส้นทางที่ยาวที่สุดจาก x ไปยัง y ทุกรายการที่ขึ้นอยู่กับ x ได้ ใช้ maxrank

bazel query 'deps(//foo-tests)' --output maxrank | tail -1
85 //third_party/zlib:zutil.c

ผลลัพธ์ระบุว่ามีเส้นทางที่มีความยาว 85 ซึ่งต้องเกิดขึ้นตามลำดับในบิลด์นี้