Tham chiếu truy vấn Bazel

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Báo cáo sự cố Xem nguồn

Trang này là hướng dẫn tham khảo cho Ngôn ngữ truy vấn Bazel được dùng khi bạn sử dụng bazel query để phân tích các phần phụ thuộc của bản dựng. Phần này cũng mô tả các định dạng đầu ra mà bazel query hỗ trợ.

Để xem các trường hợp sử dụng thực tế, hãy tham khảo Hướng dẫn truy vấn Bloel.

Tham chiếu truy vấn khác

Ngoài query, chạy trên biểu đồ mục tiêu của giai đoạn sau khi tải, Bazel cũng bao gồm truy vấn biểu đồ hành độngtruy vấn có thể định cấu hình.

Truy vấn biểu đồ hành động

Truy vấn biểu đồ hành động (aquery) hoạt động trên Biểu đồ mục tiêu đã định cấu hình sau phân tích và hiển thị thông tin về Hành động, Cấu phần phần mềm và mối quan hệ của các cấu phần phần mềm đó. aquery rất hữu ích khi bạn quan tâm đến các thuộc tính của Hành động/Cấu phần phần mềm được tạo từ Biểu đồ mục tiêu đã định cấu hình. Ví dụ: các lệnh thực tế chạy và dữ liệu đầu vào, kết quả và nội dung gợi nhớ của các lệnh đó.

Để biết thêm chi tiết, hãy xem tài liệu tham khảo về truy vấn.

Truy vấn có thể định cấu hình

Truy vấn Bazel truyền thống chạy trên biểu đồ mục tiêu giai đoạn sau khi tải và do đó không có khái niệm về cấu hình và các khái niệm liên quan. Đáng chú ý là giá trị này không phân giải chính xác các câu lệnh được chọn và trả về tất cả độ phân giải đã chọn. Tuy nhiên, môi trường truy vấn có thể định cấu hình, cquery, xử lý đúng cách các cấu hình nhưng không cung cấp tất cả chức năng của truy vấn gốc này.

Để biết thêm chi tiết, hãy xem tài liệu tham khảo về truy vấn.

Ví dụ

Mọi người dùng bazel query như thế nào? Sau đây là ví dụ điển hình:

Tại sao cây //foo phụ thuộc vào //bar/baz? Hiển thị một đường dẫn:

somepath(foo/..., //bar/baz:all)

Tất cả các bài kiểm thử foo đều sử dụng được thư viện C++ nào phụ thuộc vào việc mục tiêu foo_bin có không?

kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo:foo_bin))

Mã thông báo: Cú pháp từ vựng

Biểu thức trong ngôn ngữ truy vấn bao gồm các mã thông báo sau:

  • Từ khóa, chẳng hạn như let. Từ khoá là các từ dành riêng của ngôn ngữ và mỗi từ được mô tả bên dưới. Tập hợp đầy đủ các từ khóa là:

  • Từ, chẳng hạn như "foo/..." hoặc ".*test rule" hoặc "//bar/baz:all". Nếu một chuỗi ký tự là "dấu ngoặc kép" (bắt đầu và kết thúc bằng một dấu ngoặc đơn 'hoặc bắt đầu và kết thúc bằng một dấu ngoặc kép "), thì đó là một từ. Nếu một chuỗi ký tự không được trích dẫn, thì chuỗi ký tự đó có thể vẫn được phân tích cú pháp như một từ. Các từ không được trích dẫn là chuỗi ký tự được vẽ từ các ký tự bảng chữ cái A-Za-z, chữ số 0-9 và các ký tự đặc biệt */@.-_:$~[] (dấu hoa thị, dấu gạch chéo, dấu chấm, dấu gạch ngang, dấu gạch dưới, dấu hai chấm, dấu đô la, dấu ngã, dấu ngoặc vuông trái, dấu ngoặc vuông phải). Tuy nhiên, các từ không trong dấu ngoặc kép có thể không bắt đầu bằng dấu gạch ngang - hoặc dấu hoa thị * mặc dù [tên mục tiêu][(/concepts/labels#target-names) tương đối có thể bắt đầu bằng các ký tự đó.

    Các từ không được trích dẫn cũng có thể không bao gồm các ký tự cộng với dấu + hoặc bằng ký hiệu =, mặc dù các ký tự đó được phép trong tên mục tiêu. Khi viết mã tạo biểu thức truy vấn, tên mục tiêu phải được trích dẫn.

    Việc trích dẫn cần thiết khi viết các tập lệnh tạo biểu thức truy vấn Bazel từ các giá trị do người dùng cung cấp.

     //foo:bar+wiz    # WRONG: scanned as //foo:bar + wiz.
     //foo:bar=wiz    # WRONG: scanned as //foo:bar = wiz.
     "//foo:bar+wiz"  # OK.
     "//foo:bar=wiz"  # OK.
    

    Lưu ý rằng trích dẫn này bổ sung cho bất kỳ trích dẫn nào mà shell có thể yêu cầu, chẳng hạn như:

    bazel query ' "//foo:bar=wiz" '   # single-quotes for shell, double-quotes for Bazel.
    

    Khi được trích dẫn, từ khoá được coi là các từ thông thường. Ví dụ: some là một từ khoá nhưng "một số" là một từ. Cả foo và "foo" đều là các từ.

    Tuy nhiên, hãy cẩn thận khi sử dụng dấu ngoặc đơn hoặc dấu ngoặc kép trong tên mục tiêu. Khi trích dẫn một hoặc nhiều tên mục tiêu, chỉ sử dụng một loại dấu ngoặc kép (tất cả một hoặc tất cả các dấu ngoặc kép).

    Sau đây là ví dụ về chuỗi truy vấn Java sẽ là gì:

      'a"'a'         # WRONG: Error message: unclosed quotation.
      "a'"a"         # WRONG: Error message: unclosed quotation.
      '"a" + 'a''    # WRONG: Error message: unexpected token 'a' after query expression '"a" + '
      "'a' + "a""    # WRONG: Error message: unexpected token 'a' after query expression ''a' + '
      "a'a"          # OK.
      'a"a'          # OK.
      '"a" + "a"'    # OK
      "'a' + 'a'"    # OK
    

    Chúng tôi đã chọn cú pháp này để hầu hết các trường hợp không cần dấu ngoặc kép. Ví dụ ".*test rule" (bất thường) cần có dấu ngoặc kép: bắt đầu bằng dấu chấm và chứa dấu cách. Việc trích dẫn "cc_library" là không cần thiết nhưng không vô hại.

  • Dấu câu, chẳng hạn như dấu ngoặc đơn (), dấu chấm . và dấu phẩy ,. Các từ có chứa dấu câu (ngoại trừ các ngoại lệ nêu trên) phải được trích dẫn.

Ký tự khoảng trắng bên ngoài từ được trích dẫn sẽ bị bỏ qua.

Các khái niệm về ngôn ngữ truy vấn Bazel

Ngôn ngữ truy vấn Bazel là ngôn ngữ của biểu thức. Mỗi biểu thức đánh giá một nhóm mục tiêu được sắp xếp theo một phần hoặc tương đương, biểu đồ (DAG) mục tiêu. Đây là loại dữ liệu duy nhất.

Tập hợp và biểu đồ đề cập đến cùng một kiểu dữ liệu, nhưng nhấn mạnh các khía cạnh khác nhau của kiểu dữ liệu đó, ví dụ:

  • Đặt: Thứ tự của các mục tiêu không thú vị.
  • Biểu đồ: Thứ tự của các mục tiêu có ý nghĩa rất quan trọng.

Các chu kỳ trong biểu đồ phần phụ thuộc

Biểu đồ phần phụ thuộc của bản dựng phải không theo chu kỳ.

Các thuật toán mà ngôn ngữ truy vấn sử dụng nhằm mục đích sử dụng trong các biểu đồ không chu trình, nhưng mạnh mẽ dựa trên các chu kỳ. Thông tin chi tiết về cách xử lý các chu kỳ không được chỉ định và không nên dựa vào.

Các phần phụ thuộc ngầm ẩn

Ngoài việc xây dựng các phần phụ thuộc được xác định rõ ràng trong tệp BUILD, Bazel còn thêm các phần phụ thuộc ngầm ẩn khác vào quy tắc. Ví dụ: mọi quy tắc Java đều phụ thuộc hoàn toàn vào JavaBuilder. Các phần phụ thuộc ngầm ẩn được thiết lập bằng cách sử dụng các thuộc tính bắt đầu bằng $ và không thể bị ghi đè trong các tệp BUILD.

Theo mặc định, bazel query sẽ tính đến các phần phụ thuộc ngầm ẩn khi tính toán kết quả truy vấn. Bạn có thể thay đổi hành vi này bằng tuỳ chọn --[no]implicit_deps. Xin lưu ý rằng vì truy vấn không xem xét cấu hình, nên các chuỗi công cụ tiềm năng sẽ không bao giờ được xem xét.

Âm thanh

Biểu thức ngôn ngữ truy vấn Bazel hoạt động trên biểu đồ phần phụ thuộc của bản dựng, là biểu đồ được xác định ngầm bằng tất cả các khai báo quy tắc trong tất cả tệp BUILD. Điều quan trọng bạn cần hiểu là biểu đồ này có tính trừu tượng và không tạo thành nội dung mô tả đầy đủ về cách thực hiện tất cả các bước của bản dựng. Để tạo bản dựng, bạn cũng cần phải có cấu hình; hãy xem phần cấu hình trong Hướng dẫn sử dụng để biết thêm thông tin chi tiết.

Kết quả đánh giá một biểu thức trong ngôn ngữ truy vấn Bazel là đúng cho tất cả các cấu hình, có nghĩa là biểu thức đó có thể là khoảng ước tính quá thận trọng và không chính xác. Nếu bạn sử dụng công cụ truy vấn để tính toán tập hợp tất cả các tệp nguồn cần thiết trong khi xây dựng, công cụ truy vấn này có thể báo cáo nhiều hơn mức cần thiết, vì ví dụ: công cụ truy vấn sẽ bao gồm tất cả các tệp cần để hỗ trợ việc dịch thông báo, mặc dù bạn không có ý định sử dụng tính năng đó trong bản dựng.

Về việc duy trì thứ tự biểu đồ

Các thao tác giúp giữ lại mọi hạn chế về thứ tự kế thừa từ biểu thức phụ. Bạn có thể xem đây là "quy luật bảo toàn thứ tự một phần". Hãy cân nhắc ví dụ: nếu bạn đưa ra một truy vấn để xác định việc đóng bắc cầu của các phần phụ thuộc của một mục tiêu cụ thể, thì tập hợp kết quả sẽ được sắp xếp theo biểu đồ phần phụ thuộc. Nếu bạn lọc để chỉ bao gồm các mục tiêu thuộc loại file, thì mối quan hệ thứ tự tạm thời giữa các mục tiêu sẽ không thay đổi giữa tất cả các cặp mục tiêu trong tập hợp con tương ứng, mặc dù không có cặp nào trong số này thực sự được kết nối trực tiếp trong biểu đồ ban đầu. (Không có cạnh tệp tệp nào trong biểu đồ phần phụ thuộc bản dựng).

Tuy nhiên, mặc dù tất cả các toán tử đều giữ nguyên thứ tự, nhưng một số thao tác, chẳng hạn như các thao tác đã đặt không giới thiệu bất kỳ ràng buộc nào về thứ tự của chúng. Hãy cân nhắc biểu thức này:

deps(x) union y

Thứ tự của tập hợp kết quả cuối cùng được đảm bảo duy trì tất cả các điều kiện ràng buộc về thứ tự của các biểu thức phụ, cụ thể là tất cả phần phụ thuộc bắc cầu của x đều được sắp xếp theo đúng thứ tự và được tôn trọng lẫn nhau. Tuy nhiên, truy vấn không đảm bảo về thứ tự của các mục tiêu trong y cũng như thứ tự của các mục tiêu trong deps(x) so với các mục tiêu trong y (ngoại trừ các mục tiêu trong y cũng xảy ra trong deps(x)).

Các toán tử đưa ra giới hạn về thứ tự bao gồm: allpaths, deps, rdeps, somepath và ký tự đại diện mẫu mục tiêu package:*, dir/..., v.v.

Truy vấn Sky

Truy vấn Bầu trời là một chế độ truy vấn hoạt động trên phạm vi vũ trụ được chỉ định.

Các hàm đặc biệt chỉ có trong SkyQuery

Chế độ Sky Query có các hàm truy vấn bổ sung allrdepsrbuildfiles. Các hàm này hoạt động trên toàn bộ phạm vi vũ trụ (đó là lý do các hàm này không có ý nghĩa với một Truy vấn thông thường).

Chỉ định một phạm vi vũ trụ

Chế độ Sky Query được kích hoạt bằng cách truyền hai cờ sau: (--universe_scope hoặc --infer_universe_scope) và --order_output=no. --universe_scope=<target_pattern1>,...,<target_patternN> thông báo cho truy vấn Sau đó, tất cả các truy vấn được đánh giá trong "phạm vi" này. Cụ thể, các toán tử allrdepsrbuildfiles chỉ trả về kết quả từ phạm vi này. --infer_universe_scope yêu cầu Bazel suy ra giá trị cho --universe_scope qua biểu thức truy vấn. Giá trị dự đoán này là danh sách các mẫu mục tiêu duy nhất trong biểu thức truy vấn, nhưng đây có thể không phải là mẫu bạn muốn. Ví dụ:

bazel query --infer_universe_scope --order_output=no "allrdeps(//my:target)"

Danh sách các mẫu mục tiêu duy nhất trong biểu thức truy vấn này là ["//my:target"], vì vậy, Bazel xử lý việc này giống như lệnh gọi:

bazel query --universe_scope=//my:target --order_output=no "allrdeps(//my:target)"

Nhưng kết quả của truy vấn đó với --universe_scope chỉ là //my:target; không có phần phụ thuộc đảo ngược nào của //my:target nằm trong vũ trụ, bởi cấu trúc! Mặt khác, hãy cân nhắc:

bazel query --infer_universe_scope --order_output=no "tests(//a/... + b/...) intersect allrdeps(siblings(rbuildfiles(my/starlark/file.bzl)))"

Đây là một lệnh gọi truy vấn có ý nghĩa đang cố tính toán các mục tiêu kiểm thử trong quá trình mở rộng tests của các mục tiêu trong một số thư mục phụ thuộc bắc cầu vào các mục tiêu có định nghĩa sử dụng một tệp .bzl nhất định. Ở đây, --infer_universe_scope là một thuận tiện, đặc biệt trong trường hợp lựa chọn --universe_scope sẽ yêu cầu bạn tự phân tích cú pháp biểu thức truy vấn.

Vì vậy, đối với các biểu thức truy vấn sử dụng toán tử trong phạm vi vũ trụ như allrdepsrbuildfiles, hãy đảm bảo bạn chỉ sử dụng --infer_universe_scope nếu hành vi của toán tử này là nội dung bạn muốn.

Truy vấn Sky có một số ưu và nhược điểm so với truy vấn mặc định. Điểm bất lợi chính là không thể sắp xếp đầu ra theo thứ tự biểu đồ, do đó, một số định dạng đầu ra nhất định sẽ bị cấm. Ưu điểm của tính năng này là cung cấp hai toán tử (allrdepsrbuildfiles) không có trong truy vấn mặc định. Ngoài ra, Sky Query thực hiện công việc của mình bằng cách xem xét biểu đồ Skyframe, thay vì tạo một biểu đồ mới, đây là chức năng triển khai mặc định. Do đó, có một số trường hợp tốc độ nhanh hơn và sử dụng ít bộ nhớ hơn.

Biểu thức: Cú pháp và ngữ nghĩa của ngữ pháp

Đây là ngữ pháp của ngôn ngữ truy vấn Bazel, được biểu thị bằng ký hiệu EBNF:

expr ::= word
       | let name = expr in expr
       | (expr)
       | expr intersect expr
       | expr ^ expr
       | expr union expr
       | expr + expr
       | expr except expr
       | expr - expr
       | set(word *)
       | word '(' int | word | expr ... ')'

Các phần sau đây mô tả từng quá trình sản xuất ngữ pháp này theo thứ tự.

Mẫu mục tiêu

expr ::= word

Về tổng thể, mẫu mục tiêu chỉ là một từ. Điều này được diễn giải là tập hợp các mục tiêu (không theo thứ tự). Mẫu mục tiêu đơn giản nhất là nhãn, xác định một mục tiêu duy nhất (tệp hoặc quy tắc). Ví dụ: mẫu mục tiêu //foo:bar đánh giá thành một tập hợp chứa một phần tử, mục tiêu và quy tắc bar.

Các mẫu mục tiêu tổng quát hoá nhãn để đưa ký tự đại diện vào các gói và mục tiêu. Ví dụ: foo/...:all (hoặc chỉ foo/...) là một mẫu mục tiêu đánh giá một tập hợp chứa tất cả quy tắc trong mỗi gói định kỳ bên trong thư mục foo; bar/baz:all là một mẫu mục tiêu đánh giá cho một tập hợp chứa tất cả các quy tắc trong gói bar/baz, nhưng không phải gói con của gói đó.

Tương tự, foo/...:* là một mẫu mục tiêu đánh giá thành một nhóm chứa tất cả mục tiêu (quy tắc tệp) trong mọi gói bên dưới thư mục foo; bar/baz:* sẽ đánh giá theo một nhóm chứa tất cả mục tiêu trong gói bar/baz, nhưng không đánh giá các gói con của gói đó.

Vì ký tự đại diện :* khớp với các tệp cũng như quy tắc nên kết quả này thường hữu ích hơn :all đối với các truy vấn. Ngược lại, ký tự đại diện :all (ngầm ẩn trong các mẫu mục tiêu như foo/...) thường hữu ích hơn cho các bản dựng.

Mẫu mục tiêu bazel query hoạt động giống như mục tiêu bản dựng bazel build. Để biết thêm thông tin chi tiết, hãy xem Mẫu mục tiêu hoặc loại bazel help target-syntax.

Các mẫu mục tiêu có thể đánh giá thành một nhóm singleton (trong trường hợp của một nhãn) thành một nhóm chứa nhiều phần tử (như trong trường hợp foo/... có hàng nghìn phần tử) hoặc với nhóm trống nếu mẫu mục tiêu không khớp với mục tiêu.

Tất cả các nút trong kết quả của biểu thức mẫu mục tiêu đều được sắp xếp theo đúng thứ tự tương đối với nhau theo mối quan hệ phần phụ thuộc. Do đó, kết quả của foo:* không chỉ là tập hợp các mục tiêu trong gói foo mà còn là biểu đồ về các mục tiêu đó. (Không đảm bảo về thứ tự tương đối của các nút kết quả so với các nút khác.) Để biết thêm thông tin, hãy xem phần thứ tự biểu đồ.

Biến

expr ::= let name = expr1 in expr2
       | $name

Ngôn ngữ truy vấn Bazel cho phép định nghĩa và tham chiếu đến các biến. Kết quả đánh giá biểu thức let giống với kết quả của expr2, với tất cả các lần xuất hiện miễn phí của biến name được thay thế bằng giá trị của expr1.

Ví dụ: let v = foo/... in allpaths($v, //common) intersect $v tương đương với allpaths(foo/...,//common) intersect foo/....

Đã xảy ra lỗi khi tham chiếu biến name khác với trong biểu thức let name = ... kèm theo. Nói cách khác, biểu thức truy vấn cấp cao nhất không thể có biến miễn phí.

Trong các quy tắc ngữ pháp nêu trên, name giống như từ, nhưng có một điều kiện ràng buộc khác là mã nhận dạng pháp lý trong ngôn ngữ lập trình C. Tham chiếu đến biến phải được thêm vào trước ký tự "$".

Mỗi biểu thức let chỉ xác định một biến, nhưng bạn có thể lồng chúng.

Cả mẫu mục tiêu và tệp đối chiếu biến chỉ bao gồm một mã thông báo duy nhất, một từ, tạo ra sự không rõ ràng về cú pháp. Tuy nhiên, không có ngữ nghĩa không rõ ràng, vì một số từ là tên biến hợp pháp sẽ không được phân tách khỏi tập hợp con các từ là mẫu mục tiêu pháp lý.

Về mặt kỹ thuật, biểu thức let không làm tăng khả năng biểu đạt của ngôn ngữ truy vấn: mọi truy vấn có thể biểu thị trong ngôn ngữ cũng có thể được biểu thị mà không có các biểu thức đó. Tuy nhiên, các quy tắc này sẽ cải thiện tính chính xác của nhiều cụm từ tìm kiếm và cũng có thể giúp đánh giá cụm từ tìm kiếm hiệu quả hơn.

Biểu thức trong dấu ngoặc đơn

expr ::= (expr)

Dấu ngoặc đơn liên kết các biểu thức phụ để buộc sắp xếp thứ tự đánh giá. Biểu thức có dấu ngoặc đơn sẽ đánh giá giá trị của đối số.

Phép toán đại số:

expr ::= expr intersect expr
       | expr ^ expr
       | expr union expr
       | expr + expr
       | expr except expr
       | expr - expr

Ba toán tử này sẽ tính toán các thao tác đã đặt thông thường cho các đối số của chúng. Mỗi toán tử có hai dạng, một dạng danh nghĩa, chẳng hạn như intersect, và một dạng biểu tượng, chẳng hạn như ^. Cả hai dạng thức đều tương đương nhau; các biểu tượng tượng trưng cho tốc độ nhập nhanh hơn. (Để làm rõ phần còn lại của trang này, hãy sử dụng các dạng danh nghĩa.)

Ví dụ:

foo/... except foo/bar/...

cho số mục tiêu khớp với foo/... nhưng không khớp với foo/bar/....

Bạn có thể viết cùng một truy vấn như:

foo/... - foo/bar/...

Các phép toán intersect (^) và union (+) mang tính giao hoán (đối xứng); except (-) không đối xứng. Trình phân tích cú pháp coi cả ba toán tử là kết hợp trái và có mức độ ưu tiên bằng nhau, vì vậy bạn có thể cần dấu ngoặc đơn. Ví dụ: hai biểu thức đầu tiên là tương đương nhau, nhưng biểu thức thứ ba không:

x intersect y union z
(x intersect y) union z
x intersect (y union z)

Đọc mục tiêu từ một nguồn bên ngoài: đã đặt

expr ::= set(word *)

Toán tử set(a b c ...) tính toán sự hợp nhất của một hoặc nhiều mẫu mục tiêu, được phân tách bằng khoảng trắng (không có dấu phẩy).

Cùng với tính năng $(...) của Bourne shell, set() cung cấp phương tiện lưu kết quả của một truy vấn trong một tệp văn bản thông thường, thao tác với tệp văn bản đó bằng cách sử dụng các chương trình khác (chẳng hạn như các công cụ shell UNIX chuẩn) và sau đó đưa kết quả trở lại công cụ truy vấn dưới dạng giá trị để xử lý thêm. Ví dụ:

bazel query deps(//my:target) --output=label | grep ... | sed ... | awk ... > foo
bazel query "kind(cc_binary, set($(<foo)))"

Trong ví dụ tiếp theo, kind(cc_library, deps(//some_dir/foo:main, 5)) được tính toán bằng cách lọc dựa trên các giá trị maxrank thông qua một chương trình awk.

bazel query 'deps(//some_dir/foo:main)' --output maxrank | awk '($1 < 5) { print $2;} ' > foo
bazel query "kind(cc_library, set($(<foo)))"

Trong những ví dụ này, $(<foo) là viết tắt của $(cat foo), nhưng bạn cũng có thể sử dụng các lệnh shell ngoài cat —chẳng hạn như lệnh awk trước đó.

Hàm

expr ::= word '(' int | word | expr ... ')'

Ngôn ngữ truy vấn xác định một số hàm. Tên của hàm xác định số lượng và loại đối số mà hàm yêu cầu. Có các hàm sau:

Đóng tạm thời các phần phụ thuộc: phần phụ thuộc

expr ::= deps(expr)
       | deps(expr, depth)

Toán tử deps(x) đánh giá biểu đồ được tạo bằng cách đóng cửa các phần phụ thuộc của tập hợp đối số x bắc cầu. Ví dụ: Giá trị của deps(//foo) là biểu đồ phần phụ thuộc gốc tại nút foo duy nhất, bao gồm tất cả các phần phụ thuộc. Giá trị của deps(foo/...) là các biểu đồ phần phụ thuộc có gốc là tất cả các quy tắc trong mọi gói bên dưới thư mục foo. Trong trường hợp này, "phần phụ thuộc" chỉ có nghĩa là quy tắc và mục tiêu tệp. Do đó, các tệp BUILD và Starlark cần thiết để tạo các mục tiêu này không được đưa vào đây. Để làm được điều đó, bạn nên dùng toán tử buildfiles.

Biểu đồ kết quả được sắp xếp theo mối quan hệ phần phụ thuộc. Để biết thêm thông tin, hãy xem phần về thứ tự biểu đồ.

Toán tử deps chấp nhận đối số thứ hai tuỳ chọn. Đây là một đối số số nguyên xác định một giới hạn trên của chiều sâu của kết quả tìm kiếm. Vì vậy, deps(foo:*, 0) trả về tất cả mục tiêu trong gói foo, trong khi deps(foo:*, 1) bao gồm thêm các điều kiện tiên quyết trực tiếp của mọi mục tiêu trong gói foodeps(foo:*, 2) bao gồm thêm các nút có thể truy cập trực tiếp từ các nút trong deps(foo:*, 1), v.v. (Các con số này tương ứng với thứ hạng được hiển thị ở định dạng đầu ra minrank.) Nếu bạn bỏ qua tham số depth, thì cụm từ tìm kiếm sẽ không bị ràng buộc: từ đó tính toán việc đóng phản ứng trước về điều kiện tiên quyết.

Đóng bắc cầu các phần phụ thuộc đảo ngược: rdeps

expr ::= rdeps(expr, expr)
       | rdeps(expr, expr, depth)

Toán tử rdeps(u, x) đánh giá các phần phụ thuộc đảo ngược của đối số đã đặt x trong quá trình đóng bắc cầu của tập hợp vũ trụ u.

Biểu đồ kết quả được sắp xếp theo mối quan hệ phần phụ thuộc. Hãy xem phần về thứ tự biểu đồ để biết thêm chi tiết.

Toán tử rdeps chấp nhận một đối số thứ ba không bắt buộc. Đây là đối số số nguyên xác định một giới hạn trên của chiều sâu của kết quả tìm kiếm. Biểu đồ kết quả chỉ bao gồm các nút trong khoảng cách độ sâu đã chỉ định từ bất kỳ nút nào trong tập hợp đối số. Vì vậy, rdeps(//foo, //common, 1) đánh giá tất cả các nút trong quá trình đóng bắc cầu của //foo phụ thuộc trực tiếp vào //common. (Các số này tương ứng với thứ hạng hiển thị trong định dạng đầu ra minrank.) Nếu thông số depth bị bỏ qua, thì nội dung tìm kiếm sẽ không bị ràng buộc.

Đóng bắc cầu của tất cả phần phụ thuộc đảo ngược: allrdeps

expr ::= allrdeps(expr)
       | allrdeps(expr, depth)

Toán tử allrdeps hoạt động giống như toán tử rdeps, ngoại trừ "tập hợp vũ trụ" là bất cứ nội dung nào của cờ --universe_scope được đánh giá, thay vì được chỉ định riêng. Do đó, nếu --universe_scope=//foo/... đã được truyền, thì allrdeps(//bar) sẽ tương đương với rdeps(//foo/..., //bar).

Các phần phụ thuộc đảo ngược trực tiếp trong cùng một gói: Same_pkg_direct_rdeps

expr ::= same_pkg_direct_rdeps(expr)

Toán tử same_pkg_direct_rdeps(x) đánh giá đến toàn bộ mục tiêu trong cùng một gói với mục tiêu trong tập hợp đối số và trực tiếp phụ thuộc vào mục tiêu này.

Xử lý gói mục tiêu: anh chị em

expr ::= siblings(expr)

Toán tử siblings(x) sẽ chuyển sang tập hợp đầy đủ các mục tiêu trong cùng một gói với mục tiêu trong tập hợp đối số.

Lựa chọn tùy ý: một số lựa chọn

expr ::= some(expr)
       | some(expr, count )

Toán tử some(x, k) chọn tối đa k mục tiêu tuỳ ý từ nhóm đối số x và đánh giá thành một tập chỉ chứa các mục tiêu đó. Tham số k là không bắt buộc; nếu thiếu, kết quả sẽ là một tập hợp singleton chỉ chứa một mục tiêu được chọn tùy ý. Nếu kích thước của nhóm đối số x nhỏ hơn k, thì toàn bộ nhóm đối số x sẽ được trả về.

Ví dụ: biểu thức some(//foo:main union //bar:baz) đánh giá thành một tập hợp singleton chứa //foo:main hoặc //bar:baz, mặc dù biểu thức nào chưa được xác định. Biểu thức some(//foo:main union //bar:baz, 2) hoặc some(//foo:main union //bar:baz, 3) trả về cả //foo:main//bar:baz.

Nếu đối số là một singleton, thì some sẽ tính toán hàm nhận dạng: some(//foo:main) tương đương với //foo:main.

Sẽ xảy ra lỗi nếu tập đối số được chỉ định trống, như trong biểu thức some(//foo:main intersect //bar:baz).

Toán tử đường dẫn: somepath, allpath

expr ::= somepath(expr, expr)
       | allpaths(expr, expr)

Toán tử somepath(S, E)allpaths(S, E) tính toán đường dẫn giữa hai nhóm mục tiêu. Cả hai truy vấn đều chấp nhận hai đối số, một tập hợp S các điểm xuất phát và một tập hợp E các điểm kết thúc. somepath trả về biểu đồ nút trên một số đường dẫn tùy ý từ một mục tiêu trong S đến một mục tiêu trong E; allpaths trả về biểu đồ các nút trên tất cả các đường dẫn từ bất kỳ mục tiêu nào trong S đến bất kỳ mục tiêu nào trong E.

Các biểu đồ kết quả được sắp xếp theo mối quan hệ phụ thuộc. Hãy xem phần về thứ tự biểu đồ để biết thêm chi tiết.

Đường dẫn một số
somepath(S1 + S2, E), một kết quả có thể xảy ra.
Đường dẫn một số
somepath(S1 + S2, E), một kết quả khác có thể xảy ra.
Đường dẫn
allpaths(S1 + S2, E)

Lọc loại mục tiêu: loại

expr ::= kind(word, expr)

Toán tử kind(pattern, input) áp dụng một bộ lọc cho một tập hợp các mục tiêu và loại bỏ các mục tiêu đó không thuộc loại dự kiến. Thông số pattern chỉ định loại mục tiêu cần khớp.

Ví dụ: minh hoạ các loại cho bốn mục tiêu được xác định bởi tệp BUILD (cho gói p) như bên dưới:

Mục tiêu Loại
        genrule(
            name = "a",
            srcs = ["a.in"],
            outs = ["a.out"],
            cmd = "...",
        )
      
//p:a quy tắc genrule
//p:a.in tệp nguồn
//p:a.out tệp đã tạo
//p:BUILD tệp nguồn

Do đó, kind("cc_.* rule", foo/...) đánh giá tập hợp tất cả cc_library, cc_binary, v.v. nhắm mục tiêu theo quy tắc bên dưới fookind("source file", deps(//foo)) sẽ đánh giá tập hợp của tất cả các tệp nguồn trong hoạt động đóng bắc cầu của các phần phụ thuộc của mục tiêu //foo.

Việc trích dẫn đối số pattern thường là bắt buộc vì nếu không có đối số này, nhiều biểu thức chính quy, chẳng hạn như source file.*_test, không được trình phân tích cú pháp coi là các từ.

Khi so khớp với package group, các mục tiêu kết thúc bằng :all có thể không mang lại kết quả nào. Thay vào đó, hãy sử dụng :all-targets.

Lọc tên mục tiêu: bộ lọc

expr ::= filter(word, expr)

Toán tử filter(pattern, input) áp dụng một bộ lọc cho một tập hợp các mục tiêu và loại bỏ các mục tiêu có nhãn (ở dạng tuyệt đối) không khớp với mẫu; bộ lọc sẽ đánh giá một tập hợp con dữ liệu đầu vào tương ứng.

Đối số đầu tiên, pattern là một từ chứa biểu thức chính quy thay vì tên mục tiêu. Biểu thức filter đánh giá cho tập hợp chứa tất cả mục tiêu x sao cho x là thành viên của tập hợp input và nhãn (ở dạng tuyệt đối, chẳng hạn như //foo:bar) của x chứa nội dung khớp (không neo) đối với biểu thức chính quy pattern. Vì tất cả tên mục tiêu bắt đầu bằng //, nên tên này có thể được dùng thay thế cho neo biểu thức chính quy ^.

Toán tử này thường cung cấp một tuỳ chọn thay thế nhanh hơn và mạnh mẽ hơn nhiều cho toán tử intersect. Ví dụ: để xem tất cả phần phụ thuộc bar của mục tiêu //foo:foo, bạn có thể đánh giá

deps(//foo) intersect //bar/...

Tuy nhiên, câu lệnh này sẽ yêu cầu phân tích cú pháp tất cả tệp BUILD trong cây bar, việc này sẽ chậm và dễ xảy ra lỗi trong các tệp BUILD không liên quan. Cách khác là:

filter(//bar, deps(//foo))

trước tiên sẽ tính toán tập hợp các phần phụ thuộc //foo rồi chỉ lọc các mục tiêu khớp với mẫu đã cung cấp—nói cách khác, các mục tiêu có tên chứa //bar dưới dạng chuỗi con.

Một cách sử dụng phổ biến khác của toán tử filter(pattern, expr) là lọc các tệp cụ thể theo tên hoặc phần mở rộng của các tệp đó. Ví dụ:

filter("\.cc$", deps(//foo))

sẽ cung cấp danh sách tất cả .cc tệp dùng để xây dựng //foo.

Lọc thuộc tính quy tắc: thuộc tính

expr ::= attr(word, word, expr)

Toán tử attr(name, pattern, input) áp dụng bộ lọc cho một tập hợp các mục tiêu và loại bỏ các mục tiêu không phải là quy tắc, các mục tiêu quy tắc không có thuộc tính name được xác định hoặc các mục tiêu quy tắc mà giá trị thuộc tính không khớp với biểu thức chính quy pattern đã cung cấp. Tiêu chí này sẽ đánh giá một tập hợp con các giá trị đầu vào.

Đối số đầu tiên, name là tên của thuộc tính quy tắc sẽ được so khớp với mẫu biểu thức chính quy đã cung cấp. Đối số thứ hai, pattern là một biểu thức chính quy trên các giá trị thuộc tính. Biểu thức attr đánh giá cho tập hợp chứa tất cả mục tiêu x sao cho x là thành viên của tập hợp input, là một quy tắc có thuộc tính name được xác định và giá trị thuộc tính chứa một kết quả phù hợp (không neo) cho biểu thức chính quy pattern. Nếu name là thuộc tính không bắt buộc và quy tắc không chỉ định rõ ràng, thì giá trị thuộc tính mặc định sẽ được dùng để so sánh. Ví dụ:

attr(linkshared, 0, deps(//foo))

sẽ chọn tất cả phần phụ thuộc //foo được phép đặt thuộc tính đường liên kết (chẳng hạn như quy tắc cc_binary) và đặt thuộc tính này là 0 hoặc không đặt gì nhưng giá trị mặc định là 0 (chẳng hạn như cho các quy tắc cc_binary).

Các thuộc tính loại danh sách (chẳng hạn như srcs, data, v.v.) được chuyển đổi thành các chuỗi có dạng [value<sub>1</sub>, ..., value<sub>n</sub>], bắt đầu bằng dấu ngoặc [, kết thúc bằng dấu ngoặc ] và sử dụng "," (dấu phẩy, dấu cách) để phân tách nhiều giá trị. Nhãn được chuyển đổi thành các chuỗi bằng cách sử dụng hình thức tuyệt đối của nhãn. Ví dụ: thuộc tính deps=[":foo", "//otherpkg:bar", "wiz"] sẽ được chuyển đổi thành chuỗi [//thispkg:foo, //otherpkg:bar, //thispkg:wiz]. Các dấu ngoặc vuông luôn hiển thị, vì vậy, danh sách trống sẽ sử dụng giá trị chuỗi [] cho mục đích so khớp. Ví dụ:

attr("srcs", "\[\]", deps(//foo))

sẽ chọn tất cả quy tắc trong số các phần phụ thuộc //foo có thuộc tính srcs trống, trong khi

attr("data", ".{3,}", deps(//foo))

sẽ chọn tất cả quy tắc trong số các phần phụ thuộc //foo chỉ định ít nhất một giá trị trong thuộc tính data (mỗi nhãn dài ít nhất 3 ký tự do //:).

Để chọn tất cả quy tắc trong số các phần phụ thuộc //foo có một value cụ thể trong thuộc tính loại danh sách, hãy sử dụng

attr("tags", "[\[ ]value[,\]]", deps(//foo))

Hàm này hoạt động vì ký tự trước value sẽ là [ hoặc một dấu cách và ký tự sau value sẽ là dấu phẩy hoặc ].

Lọc chế độ hiển thị quy tắc: hiển thị

expr ::= visible(expr, expr)

Toán tử visible(predicate, input) sẽ áp dụng một bộ lọc cho một tập hợp các mục tiêu và loại bỏ các mục tiêu mà không cần hiển thị theo yêu cầu.

Đối số đầu tiên, predicate, là một tập hợp các mục tiêu mà tất cả các mục tiêu trong kết quả phải hiển thị. Biểu thức visible đánh giá với tập hợp chứa tất cả mục tiêu x, trong đó x là thành viên của tập hợp input và cho tất cả mục tiêu y trong predicatex sẽ hiển thị cho y. Ví dụ:

visible(//foo, //bar:*)

sẽ chọn tất cả mục tiêu trong gói //bar//foo có thể phụ thuộc vào mà không vi phạm các quy định hạn chế về khả năng hiển thị.

Đánh giá các thuộc tính quy tắc của nhãn loại: nhãn

expr ::= labels(word, expr)

Toán tử labels(attr_name, inputs) trả về tập hợp các mục tiêu được chỉ định trong thuộc tính attr_name thuộc loại "nhãn" hoặc "danh sách nhãn" trong một số quy tắc trong tập hợp inputs.

Ví dụ: labels(srcs, //foo) trả về tập hợp các mục tiêu xuất hiện trong thuộc tính srcs của quy tắc //foo. Nếu có nhiều quy tắc với thuộc tính srcs trong tập hợp inputs, hệ thống sẽ trả về kết hợp của srcs.

Mở rộng và lọc test_ suites: thử nghiệm

expr ::= tests(expr)

Toán tử tests(x) trả về tập hợp tất cả các quy tắc kiểm thử trong tập hợp x, mở rộng mọi quy tắc test_suite vào tập hợp các kiểm thử riêng lẻ mà các tham chiếu đó tham chiếu đến và áp dụng tính năng lọc theo tagsize.

Theo mặc định, tính năng đánh giá truy vấn sẽ bỏ qua mọi mục tiêu không thử nghiệm trong tất cả quy tắc test_suite. Bạn có thể thay đổi tuỳ chọn này thành lỗi với tuỳ chọn --strict_test_suite.

Ví dụ: truy vấn kind(test, foo:*) liệt kê tất cả quy tắc *_testtest_suite trong gói foo. Tất cả kết quả đều là thành viên (theo định nghĩa) của gói foo. Ngược lại, truy vấn tests(foo:*) sẽ trả về tất cả kiểm thử riêng lẻ sẽ được thực thi bởi bazel test foo:*: điều này có thể bao gồm các kiểm thử thuộc các gói khác, được tham chiếu trực tiếp hoặc gián tiếp qua quy tắc test_suite.

Tệp định nghĩa gói: buildfiles

expr ::= buildfiles(expr)

Toán tử buildfiles(x) sẽ trả về tập hợp các tệp xác định các gói của từng mục tiêu trong tập hợp x; nói cách khác, đối với mỗi gói, tệp BUILD của mục đó cộng với mọi tệp .bzl được tham chiếu qua load. Lưu ý rằng thao tác này cũng trả về tệp BUILD của các gói chứa các tệp load.

Toán tử này thường được dùng khi xác định tệp hoặc gói nào là cần thiết để tạo một mục tiêu đã chỉ định, thường kết hợp với tuỳ chọn --output package ở bên dưới. Ví dụ:

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

trả về tập hợp tất cả các gói mà //foo phụ thuộc bắc cầu.

buildfiles Do đó, buildfiles không biên dịch tốt bằng các toán tử truy vấn khác và kết quả của nó có thể gây hiểu lầm khi được định dạng theo cách có cấu trúc, chẳng hạn như [--output=xml](#output-xml).

Tệp định nghĩa gói: rbuildfiles

expr ::= rbuildfiles(word, ...)

Toán tử rbuildfiles lấy danh sách các mảnh đường dẫn được phân tách bằng dấu phẩy và trả về nhóm tệp BUILD phụ thuộc bắc cầu vào các mảnh đường dẫn này. Ví dụ: nếu //foo là một gói, thì rbuildfiles(foo/BUILD) sẽ trả về mục tiêu //foo:BUILD. Nếu tệp foo/BUILDload('//bar:file.bzl'... thì rbuildfiles(bar/file.bzl) sẽ trả về mục tiêu //foo:BUILD cũng như mục tiêu cho mọi tệp BUILD khác tải //bar:file.bzl

Phạm vi của toán tử rbuildfiles là vũ trụ được cờ --universe_scope chỉ định. Các tệp không tương ứng trực tiếp với tệp BUILD và tệp .bzl sẽ không ảnh hưởng đến kết quả. Ví dụ: các tệp nguồn (như foo.cc) sẽ bị bỏ qua, ngay cả khi các tệp này được đề cập rõ ràng trong tệp BUILD. Tuy nhiên, các đường liên kết tượng trưng sẽ được tuân thủ để nếu foo/BUILD là một đường liên kết tượng trưng cho bar/BUILD, thì rbuildfiles(bar/BUILD) sẽ đưa //foo:BUILD vào kết quả.

Toán tử rbuildfiles gần như là nghịch đảo về mặt đạo đức của toán tử buildfiles. Tuy nhiên, hành vi đảo ngược đạo đức này lại mạnh hơn một hướng: dữ liệu đầu ra của rbuildfiles cũng giống như dữ liệu đầu vào của buildfiles; dữ liệu đầu vào trước đây sẽ chỉ chứa BUILD mục tiêu tệp trong các gói và sau đó có thể chứa các mục tiêu như vậy. Ở hướng khác, thư từ yếu hơn. Kết quả đầu ra của toán tử buildfiles là các mục tiêu tương ứng với tất cả các gói vàbzl các tệp cần thiết cho một giá trị nhập vào nhất định. Tuy nhiên, dữ liệu đầu vào của toán tử rbuildfiles không phải là các mục tiêu đó, mà là các mảnh đường dẫn tương ứng với các mục tiêu đó.

Tệp định nghĩa gói: loadfiles

expr ::= loadfiles(expr)

Toán tử loadfiles(x) trả về tập hợp các tệp Starlark cần thiết để tải gói của mỗi mục tiêu trong bộ x. Nói cách khác, đối với mỗi gói, công cụ này sẽ trả về các tệp .bzl được tham chiếu từ tệp BUILD.

Định dạng đầu ra

bazel query tạo một biểu đồ. Bạn chỉ định nội dung, định dạng và thứ tự mà bazel query trình bày biểu đồ này thông qua tùy chọn dòng lệnh --output.

Khi chạy với Truy vấn trên không, chỉ các định dạng đầu ra tương thích với đầu ra không theo thứ tự mới được phép. Cụ thể, các định dạng đầu ra graph, minrankmaxrank đều bị cấm.

Một số định dạng đầu ra chấp nhận các tuỳ chọn bổ sung. Tên của mỗi tuỳ chọn đầu ra có tiền tố là định dạng đầu ra được áp dụng, vì vậy, --graph:factored chỉ áp dụng khi sử dụng --output=graph; việc này không có tác dụng nếu định dạng đầu ra không phải là graph được sử dụng. Tương tự, --xml:line_numbers chỉ áp dụng khi đang sử dụng --output=xml.

Theo thứ tự của kết quả

Mặc dù biểu thức truy vấn luôn tuân theo "luật tuân thủ thứ tự biểu đồ), nhưng việc trình bày kết quả có thể được thực hiện theo cách sắp xếp phụ thuộc hoặc không theo thứ tự. Việc này không ảnh hưởng đến các mục tiêu trong tập hợp kết quả hoặc cách tính truy vấn. Chỉ ảnh hưởng đến cách in kết quả ra stdout. Hơn nữa, các nút tương đương với thứ tự phần phụ thuộc có thể được hoặc không được sắp xếp theo thứ tự bảng chữ cái. Cờ --order_output có thể được dùng để kiểm soát hành vi này. (Cờ --[no]order_results có một phần nhỏ chức năng của cờ --order_output và không được dùng nữa.)

Giá trị mặc định của cờ này là auto. Giá trị này sẽ in kết quả theo thứ tự từ vựng. Tuy nhiên, khi sử dụng somepath(a,b), kết quả sẽ được in theo thứ tự deps.

Khi cờ này là no--output là một trong build, label, label_kind, location, package, proto hoặc xml, kết quả sẽ được in theo thứ tự tuỳ ý. Thường thì đây là tuỳ chọn nhanh nhất. Tính năng này không được hỗ trợ mặc dù khi --output là một trong graph, minrank hoặc maxrank: với các định dạng này, Bazel luôn in kết quả theo thứ tự hoặc thứ hạng phần phụ thuộc.

Khi cờ này là deps, Bazel sẽ đưa ra một số thứ tự cấu trúc liên kết (toptopcture) – tức là các phần phụ thuộc trước tiên. Tuy nhiên, các nút không được sắp xếp theo thứ tự phần phụ thuộc (vì không có đường dẫn từ một trong hai đường dẫn này) có thể được in theo thứ tự bất kỳ.

Khi cờ này là full, Bazel sẽ in các nút theo thứ tự hoàn toàn xác định (tổng số). Trước tiên, tất cả các nút được sắp xếp theo thứ tự bảng chữ cái. Sau đó, mỗi nút trong danh sách được dùng làm điểm bắt đầu cho lượt tìm kiếm chiều sâu đầu tiên theo thứ tự sau đó, trong đó các cạnh gửi đi tới các nút không được truy cập sẽ được chuyển tải theo thứ tự bảng chữ cái của các nút kế tiếp. Cuối cùng, các nút được in theo chiều ngược lại theo thứ tự mà các nút được truy cập.

Việc in các nút theo thứ tự này có thể chậm hơn, vì vậy bạn chỉ nên sử dụng nút này khi tính quyết định là quan trọng.

In biểu mẫu nguồn của mục tiêu khi chúng xuất hiện trong BUILD

--output build

Với tùy chọn này, cách trình bày từng mục tiêu như được viết thủ công bằng ngôn ngữ XÂY DỰNG. Tất cả biến và lệnh gọi hàm (như glob, macro), đều được mở rộng. Điều này rất hữu ích khi xem hiệu ứng của macro Starlark. Ngoài ra, mỗi quy tắc hiệu quả sẽ báo cáo một giá trị generator_name và/hoặc generator_function), cung cấp tên của macro được đánh giá để tạo ra quy tắc hiệu quả.

Mặc dù kết quả sử dụng cú pháp giống như tệp BUILD, nhưng việc này không đảm bảo sẽ tạo ra tệp BUILD hợp lệ.

--output label

Với tuỳ chọn này, tập hợp tên (hoặc nhãn) của từng mục tiêu trong biểu đồ kết quả sẽ được in, một nhãn trên mỗi dòng, theo thứ tự cấu trúc liên kết (trừ khi --noorder_results được chỉ định, hãy xem ghi chú về thứ tự kết quả). (Thứ tự cấu trúc liên kết là một thứ tự mà trong đó một biểu đồ xuất hiện sớm hơn tất cả các thành công kế tiếp.) Tất nhiên, có nhiều thứ tự cấu trúc liên kết có thể có của biểu đồ (thứ tự đảo ngược chỉ là một); lệnh được chọn sẽ không được chỉ định.

Khi in kết quả của một truy vấn somepath, thứ tự in của các nút là thứ tự của đường dẫn.

Lưu ý: trong một số trường hợp góc, có thể có hai mục tiêu riêng biệt có cùng nhãn; ví dụ: cả một quy tắc sh_binary và tệp srcs duy nhất (ngầm ẩn) đều có thể được gọi là foo.sh. Nếu kết quả của một truy vấn chứa cả hai mục tiêu này, thì kết quả (ở định dạng label) sẽ xuất hiện để chứa nội dung trùng lặp. Khi sử dụng định dạng label_kind (xem dưới đây), sự khác biệt sẽ trở nên rõ ràng: hai mục tiêu này có cùng tên, nhưng một mục tiêu có loại sh_binary rule và loại mục tiêu còn lại là source file.

--output label_kind

Giống như label, định dạng đầu ra này in nhãn của từng mục tiêu trong biểu đồ kết quả, theo thứ tự cấu trúc liên kết, nhưng nó cũng đứng trước nhãn theo loại của mục tiêu.

--output minrank --output maxrank

Giống như label, các định dạng đầu ra minrankmaxrank in nhãn của từng mục tiêu trong biểu đồ kết quả, nhưng thay vì xuất hiện theo thứ tự cấu trúc liên kết, chúng xuất hiện theo thứ tự xếp hạng, đứng sau số thứ hạng của chúng. Những kết quả này không chịu ảnh hưởng của cờ thứ tự kết quả --[no]order_results (xem ghi chú về thứ tự kết quả).

Có hai biến thể của định dạng này: minrank xếp hạng từng nút theo độ dài của đường dẫn ngắn nhất từ một nút gốc đến nút đó. Các nút "Gốc" (không có cạnh nào đến) có thứ hạng 0, các nút kế tiếp có thứ hạng 1, v.v. (Như thường lệ, các cạnh sẽ trỏ từ một mục tiêu đến điều kiện tiên quyết của mục tiêu: các mục tiêu phụ thuộc vào đó.)

maxrank xếp hạng từng nút theo độ dài của đường dẫn dài nhất từ nút gốc đến nút đó. Xin nhắc lại, "gốc" có thứ hạng là 0, tất cả các nút khác đều có thứ hạng lớn hơn thứ hạng tối đa của tất cả các phần tử trước.

Tất cả các nút trong một chu kỳ được xem là có thứ hạng bằng nhau. (Hầu hết các biểu đồ không theo chu kỳ, nhưng chu kỳ xảy ra đơn giản vì các tệp BUILD chứa chu kỳ không chính xác.)

Các định dạng đầu ra này rất hữu ích để khám phá độ sâu của biểu đồ. Nếu được dùng cho kết quả của truy vấn deps(x), rdeps(x) hoặc allpaths, thì số thứ hạng bằng với độ dài của đường dẫn ngắn nhất (có minrank) hoặc dài nhất (với maxrank) từ x đến một nút trong thứ hạng đó. Bạn có thể sử dụng maxrank để xác định trình tự các bước dài nhất cần thiết để tạo mục tiêu.

Ví dụ: biểu đồ ở bên trái tạo ra kết quả ở bên phải khi --output minrank--output maxrank được chỉ định tương ứng.

Xếp hạng
      minrank

      0 //c:c
      1 //b:b
      1 //a:a
      2 //b:b.cc
      2 //a:a.cc
      
      maxrank

      0 //c:c
      1 //b:b
      2 //a:a
      2 //b:b.cc
      3 //a:a.cc
      
--output location

Giống như label_kind, tùy chọn này sẽ in ra, đối với mỗi mục tiêu trong kết quả, loại và nhãn của mục tiêu, nhưng tiền tố đó là một chuỗi mô tả vị trí của mục tiêu đó, dưới dạng tên tệp và số dòng. Định dạng này giống với kết quả của grep. Do đó, các công cụ có thể phân tích cú pháp sau (chẳng hạn như Emacs hoặc vi) cũng có thể sử dụng đầu ra truy vấn để thực hiện một loạt các kết quả trùng khớp, cho phép dùng công cụ truy vấn Bazel làm "grep cho các tệp BUILD" dựa trên phần phụ thuộc.

Thông tin vị trí thay đổi theo loại mục tiêu (xem toán tử Kind). Đối với các quy tắc, hệ thống sẽ in vị trí khai báo của quy tắc trong tệp BUILD. Đối với các tệp nguồn, vị trí của dòng 1 của tệp thực tế sẽ được in. Đối với tệp được tạo, vị trí của quy tắc sẽ tạo tệp đó sẽ được in. (Công cụ truy vấn không có đủ thông tin để tìm vị trí thực tế của tệp đã tạo và trong mọi trường hợp, công cụ này có thể không tồn tại nếu bản dựng chưa được thực hiện.)

--output package

Tuỳ chọn này in tên của tất cả các gói chứa một số mục tiêu trong tập hợp kết quả. Tên được in theo thứ tự từ vựng; các bản sao bị loại trừ. Chính thức thì đây là một phép chiếu từ tập hợp nhãn (gói, mục tiêu) vào các gói.

Các gói trong kho lưu trữ bên ngoài được định dạng là @repo//foo/bar trong khi các gói trong kho lưu trữ chính được định dạng là foo/bar.

Cùng với truy vấn deps(...), bạn có thể dùng tùy chọn đầu ra này để tìm tập hợp các gói phải được kiểm tra để xây dựng một tập hợp mục tiêu nhất định.

Hiển thị biểu đồ của kết quả

--output graph

Tuỳ chọn này làm cho kết quả truy vấn được in dưới dạng biểu đồ hướng dẫn ở định dạng AT&T GraphViz phổ biến. Thông thường, kết quả sẽ được lưu vào một tệp, chẳng hạn như .png hoặc .svg. (Nếu chương trình dot chưa được cài đặt trên máy trạm của bạn, thì bạn có thể cài đặt chương trình này bằng lệnh sudo apt-get install graphviz.) Xem phần ví dụ bên dưới để biết lệnh gọi mẫu.

Định dạng đầu ra này đặc biệt hữu ích đối với các truy vấn allpaths, deps hoặc rdeps, trong đó kết quả bao gồm một nhóm đường dẫn không thể dễ hình dung khi hiển thị ở dạng tuyến tính, chẳng hạn như với --output label.

Theo mặc định, biểu đồ sẽ hiển thị dưới dạng hệ số. Điều này có nghĩa là các nút tương đương về mặt cấu trúc liên kết được hợp nhất với nhau thành một nút duy nhất có nhiều nhãn. Điều này giúp biểu đồ nhỏ gọn và dễ đọc hơn vì biểu đồ kết quả điển hình chứa các mẫu lặp lại nhiều. Ví dụ: một quy tắc java_library có thể phụ thuộc vào hàng trăm tệp nguồn Java, tất cả đều được tạo bởi cùng một genrule; trong biểu đồ thanh toán, tất cả các tệp này đều được biểu thị bằng một nút. Hành vi này có thể bị vô hiệu hoá với tuỳ chọn --nograph:factored.

--graph:node_limit n

Tuỳ chọn này chỉ định độ dài tối đa của chuỗi nhãn cho một nút biểu đồ trong đầu ra. Các nhãn dài hơn sẽ bị cắt ngắn; -1 sẽ tắt tính năng cắt bớt. Do hình thức in mà biểu đồ thường được in, nên các nhãn nút có thể rất dài. GraphViz không thể xử lý các nhãn vượt quá 1024 ký tự. Đây là giá trị mặc định của tuỳ chọn này. Tuỳ chọn này không có hiệu lực trừ phi bạn sử dụng --output=graph.

--[no]graph:factored

Theo mặc định, các biểu đồ sẽ xuất hiện ở dạng yếu tố, như đã giải thích ở trên. Khi bạn chỉ định --nograph:factored, các biểu đồ sẽ được in mà không tính đến yếu tố này. Điều này giúp việc hiển thị bằng GraphViz trở nên phi thực tế, nhưng định dạng đơn giản hơn có thể dễ dàng xử lý bằng các công cụ khác (chẳng hạn như grep). Tuỳ chọn này không có hiệu lực trừ khi bạn sử dụng --output=graph.

XML

--output xml

Tuỳ chọn này làm cho các mục tiêu thu được sẽ được in ở dạng XML. Đầu ra bắt đầu bằng một tiêu đề XML như sau

  <?xml version="1.0" encoding="UTF-8"?>
  <query version="2">

rồi tiếp tục với một phần tử XML cho mỗi mục tiêu trong biểu đồ kết quả, theo thứ tự cấu trúc liên kết (trừ khi được yêu cầu kết quả không theo thứ tự), và sau đó kết thúc bằng việc chấm dứt.

</query>

Các mục nhập đơn giản được phát cho các mục tiêu thuộc loại file:

  <source-file name='//foo:foo_main.cc' .../>
  <generated-file name='//foo:libfoo.so' .../>

Tuy nhiên, đối với quy tắc, XML có cấu trúc và chứa định nghĩa của tất cả các thuộc tính của quy tắc đó, bao gồm cả các thuộc tính có giá trị không được chỉ định rõ ràng trong tệp BUILD của quy tắc.

Ngoài ra, kết quả này bao gồm các phần tử rule-inputrule-output để cấu trúc liên kết của biểu đồ phần phụ thuộc có thể được tạo lại mà không cần phải biết rằng, chẳng hạn như các phần tử của thuộc tính srcs là phần phụ thuộc chuyển tiếp (điều kiện tiên quyết) và nội dung của thuộc tính outs là phần phụ thuộc ngược (người tiêu dùng).

Các phần tử rule-input cho phần phụ thuộc ngầm ẩn sẽ bị chặn nếu bạn chỉ định --noimplicit_deps.

  <rule class='cc_binary rule' name='//foo:foo' ...>
    <list name='srcs'>
      <label value='//foo:foo_main.cc'/>
      <label value='//foo:bar.cc'/>
      ...
    </list>
    <list name='deps'>
      <label value='//common:common'/>
      <label value='//collections:collections'/>
      ...
    </list>
    <list name='data'>
      ...
    </list>
    <int name='linkstatic' value='0'/>
    <int name='linkshared' value='0'/>
    <list name='licenses'/>
    <list name='distribs'>
      <distribution value="INTERNAL" />
    </list>
    <rule-input name="//common:common" />
    <rule-input name="//collections:collections" />
    <rule-input name="//foo:foo_main.cc" />
    <rule-input name="//foo:bar.cc" />
    ...
  </rule>

Mỗi phần tử XML cho một mục tiêu đều chứa một thuộc tính name, có giá trị là nhãn của mục tiêu và một thuộc tính location có giá trị là vị trí của mục tiêu được in bằng --output location.

--[no]xml:line_numbers

Theo mặc định, các vị trí được hiển thị trong đầu ra XML chứa các số dòng. Khi bạn chỉ định --noxml:line_numbers, các số dòng sẽ không được in.

--[no]xml:default_values

Theo mặc định, đầu ra XML không bao gồm thuộc tính quy tắc có giá trị là giá trị mặc định cho loại thuộc tính đó (ví dụ: nếu giá trị này không được chỉ định trong tệp BUILD hoặc giá trị mặc định được cung cấp rõ ràng). Tuỳ chọn này khiến các giá trị thuộc tính như vậy được đưa vào đầu ra XML.

Cụm từ thông dụng

Biểu thức chính quy trong ngôn ngữ truy vấn sử dụng thư viện biểu thức chính quy Java, vì vậy bạn có thể sử dụng cú pháp đầy đủ cho java.util.regex.Pattern.

Truy vấn bằng kho lưu trữ bên ngoài

Nếu bản dựng phụ thuộc vào các quy tắc từ kho lưu trữ bên ngoài (được xác định trong tệp WORKSPACE), thì kết quả truy vấn sẽ bao gồm các phần phụ thuộc này. Ví dụ: nếu //foo:bar phụ thuộc vào //external:some-lib//external:some-lib được liên kết với @other-repo//baz:lib, thì bazel query 'deps(//foo:bar)' sẽ liệt kê cả @other-repo//baz:lib//external:some-lib dưới dạng phần phụ thuộc.

Bản thân kho lưu trữ bên ngoài không phải là phần phụ thuộc của bản dựng. Điều đó có nghĩa là trong ví dụ trên, //external:other-repo không phải là phần phụ thuộc. Tuy nhiên, nội dung này có thể được truy vấn làm thành viên của gói //external, ví dụ:

  # Querying over all members of //external returns the repository.
  bazel query 'kind(http_archive, //external:*)'
  //external:other-repo

  # ...but the repository is not a dependency.
  bazel query 'kind(http_archive, deps(//foo:bar))'
  INFO: Empty results