Hàm

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.

Nội dung

gói hàng

package(default_deprecation, default_testonly, default_visibility, features)

Hàm này khai báo siêu dữ liệu áp dụng cho mọi quy tắc tiếp theo trong gói. Lệnh này được sử dụng tối đa một lần trong một gói (BUILD tệp).

Hàm package() phải được gọi ngay sau tất cả câu lệnh load() ở đầu tệp, trước mọi quy tắc.

Đối số

Thuộc tính Nội dung mô tả
default_visibility

List of labels; optional

Chế độ hiển thị mặc định của các quy tắc trong gói này.

Mọi quy tắc trong gói này đều có chế độ hiển thị được chỉ định trong thuộc tính này, trừ trường hợp có quy định khác trong thuộc tính visibility của quy tắc đó. Để biết thông tin chi tiết về cú pháp của thuộc tính này, hãy xem tài liệu về khả năng hiển thị. Chế độ hiển thị mặc định của gói không áp dụng cho exports_files (xuất tệp công khai) theo mặc định.

default_deprecation

String; optional

Đặt thông báo deprecation mặc định cho tất cả quy tắc trong gói này.

default_testonly

Boolean; optional; default is False except as noted

Đặt thuộc tính testonly mặc định cho tất cả các quy tắc trong gói này.

Trong các gói trong javatests, giá trị mặc định là 1.

features

List strings; optional

Đặt nhiều cờ ảnh hưởng đến ngữ nghĩa của tệp BUILD này.

Tính năng này chủ yếu được những người làm việc trên hệ thống xây dựng sử dụng để gắn thẻ các gói cần xử lý đặc biệt. Không sử dụng thuộc tính này trừ khi có người yêu cầu rõ ràng là người đang làm việc trên hệ thống xây dựng.

Ví dụ

Nội dung khai báo bên dưới khai báo rằng các quy tắc trong gói này chỉ hiển thị cho các thành viên của nhóm //foo:target. Các nội dung khai báo về khả năng hiển thị riêng lẻ theo quy tắc (nếu có) sẽ ghi đè thông số kỹ thuật này.
package(default_visibility = ["//foo:target"])

package_group [nhóm_nhóm]

package_group(name, packages, includes)

Hàm này xác định một tập hợp gói và liên kết nhãn với một tập hợp đó. Bạn có thể tham chiếu nhãn này trong thuộc tính visibility.

Nhóm gói hàng chủ yếu dùng để kiểm soát chế độ hiển thị. Bạn có thể tham chiếu mục tiêu hiển thị công khai từ mọi gói trong cây nguồn. Bạn chỉ có thể tham chiếu mục tiêu riêng tư hiển thị trong gói riêng (không phải gói con). Giữa các trường hợp cực đoan này, mục tiêu có thể cho phép truy cập vào gói của riêng mình cộng với bất kỳ gói nào trong số các gói được mô tả bởi một hoặc nhiều nhóm gói. Để nắm được nội dung giải thích chi tiết hơn về hệ thống hiển thị, hãy xem thuộc tính Visibility (Chế độ hiển thị).

Một gói nhất định được coi là nằm trong nhóm nếu gói đó khớp với thuộc tính packages hoặc nằm trong một trong các nhóm gói khác được đề cập trong thuộc tính includes.

Nhóm gói là mục tiêu kỹ thuật nhưng không được tạo theo quy tắc và không có bất kỳ biện pháp bảo vệ hiển thị nào.

Đối số

Thuộc tính Nội dung mô tả
name

Name; required

Tên duy nhất cho mục tiêu này.

packages

List of strings; optional

Danh sách từ 0 trở lên quy cách gói.

Mỗi chuỗi thông số kỹ thuật của gói có thể có một trong những dạng sau:

  1. Tên đầy đủ của một gói không có kho lưu trữ, bắt đầu bằng dấu gạch chéo đôi. Ví dụ: //foo/bar chỉ định gói có tên đó và gói nằm trong cùng một kho lưu trữ với nhóm gói.
  2. Như ở trên nhưng với /... theo sau. Ví dụ: //foo/... chỉ định tập hợp //foo và tất cả các gói con của tập hợp con này. //... chỉ định tất cả các gói trong kho lưu trữ hiện tại.
  3. Các chuỗi public hoặc private, tương ứng với từng gói hoặc không có gói nào. (Biểu mẫu này yêu cầu phải đặt cờ --incompatible_package_group_has_public_syntax.)

Ngoài ra, hai loại thông số kỹ thuật đầu tiên của gói cũng có thể có tiền tố - để cho biết chúng bị từ chối.

Nhóm gói chứa bất kỳ gói nào khớp với ít nhất một trong các thông số tích cực và không có thông số kỹ thuật phủ định nào. Ví dụ: giá trị [//foo/..., -//foo/tests/...] bao gồm tất cả các gói con của //foo mà không phải là gói con của //foo/tests. (Bản thân //foo được đưa vào trong khi //foo/tests không được bao gồm).

Ngoài chế độ hiển thị công khai, không có cách nào để chỉ định trực tiếp các gói bên ngoài kho lưu trữ hiện tại.

Nếu thiếu thuộc tính này, thuộc tính này giống với việc đặt giá trị cho một danh sách trống. Việc này cũng giống như việc đặt giá trị cho một danh sách chỉ chứa private.

Lưu ý: Thông số kỹ thuật //... có hành vi cũ giống với public. Hành vi này sẽ bị tắt khi bạn bật --incompatible_fix_package_group_reporoot_syntax.

Lưu ý: Khi một thuộc tính cũ được chuyển đổi tuần tự như một phần của bazel query --output=proto (hoặc --output=xml), các dấu gạch chéo ở đầu sẽ bị bỏ qua nếu bạn không bật --incompatible_package_group_includes_double_slash. Ví dụ: //pkg/foo/... sẽ xuất ra dưới dạng \"pkg/foo/...\".

includes

List of labels; optional

Các nhóm gói khác có trong gói này.

Các nhãn trong thuộc tính này phải tham chiếu đến các nhóm gói khác. Các gói trong các nhóm gói tham chiếu được lấy như một phần của nhóm gói này. Tính năng này mang tính bắc cầu — nếu nhóm gói a có nhóm gói bb bao gồm nhóm gói c, thì mọi gói trong c cũng sẽ là một thành viên của a.

Khi sử dụng cùng với thông số kỹ thuật của gói bị bỏ qua, hãy lưu ý rằng tập hợp các gói cho mỗi nhóm sẽ được tính toán độc lập trước tiên, sau đó kết quả sẽ được hợp nhất với nhau. Điều này có nghĩa là quy cách bị phủ định trong một nhóm sẽ không ảnh hưởng đến quy cách trong một nhóm khác.

Ví dụ

Khai báo package_group sau đây chỉ định một nhóm gói có tên "tropical" chứa trái cây nhiệt đới.

package_group(
    name = "tropical",
    packages = [
        "//fruits/mango",
        "//fruits/orange",
        "//fruits/papaya/...",
    ],
)

Các nội dung khai báo sau chỉ định nhóm gói của một ứng dụng hư cấu:

package_group(
    name = "fooapp",
    includes = [
        ":controller",
        ":model",
        ":view",
    ],
)

package_group(
    name = "model",
    packages = ["//fooapp/database"],
)

package_group(
    name = "view",
    packages = [
        "//fooapp/swingui",
        "//fooapp/webui",
    ],
)

package_group(
    name = "controller",
    packages = ["//fooapp/algorithm"],
)

Export_files

exports_files([label, ...], visibility, licenses)

exports_files() chỉ định danh sách các tệp thuộc gói này được xuất sang các gói khác.

Tệp BUILD cho một gói chỉ có thể tham chiếu trực tiếp đến các tệp nguồn thuộc về một gói khác nếu chúng được xuất rõ ràng bằng câu lệnh exports_files(). Đọc thêm về chế độ hiển thị của tệp.

Là một hành vi cũ, các tệp được đề cập dưới dạng dữ liệu đầu vào cho một quy tắc sẽ được xuất với chế độ hiển thị mặc định cho đến khi cờ --incompatible_no_implicit_file_export được lật. Tuy nhiên, bạn không nên dựa vào hành vi này và chủ động chuyển sang sử dụng hành vi này.

Đối số

Đối số là danh sách tên của các tệp trong gói hiện tại. Bạn cũng có thể chỉ định phần khai báo về khả năng hiển thị. Trong trường hợp này, các tệp sẽ hiển thị với các mục tiêu được chỉ định. Nếu bạn không chỉ định chế độ hiển thị, các tệp sẽ hiển thị với mọi gói, ngay cả khi chế độ hiển thị mặc định của gói đã được chỉ định trong hàm package. Bạn cũng có thể chỉ định giấy phép.

Ví dụ:

Ví dụ sau đây sẽ xuất golden.txt, một tệp văn bản từ gói test_data để các gói khác có thể sử dụng tệp này, chẳng hạn như trong thuộc tính data của kiểm thử.

# from //test_data/BUILD

exports_files(["golden.txt"])

cầu nối

glob(include, exclude=[], exclude_directories=1, allow_empty=True)

Glob là một hàm trợ giúp tìm tất cả các tệp khớp với một số mẫu đường dẫn nhất định và trả về danh sách các đường dẫn mới, có thể thay đổi, được sắp xếp. Glob chỉ tìm kiếm các tệp trong gói riêng và chỉ tìm các tệp nguồn (không phải các tệp được tạo cũng như các mục tiêu khác).

Nhãn tệp nguồn được bao gồm trong kết quả nếu đường dẫn tương đối gói của tệp khớp với bất kỳ mẫu include nào và không có mẫu exclude nào.

Danh sách includeexclude chứa các mẫu đường dẫn tương ứng với gói hiện tại. Mỗi mẫu có thể bao gồm một hoặc nhiều phân đoạn đường dẫn. Như thường lệ với các đường dẫn Unix, các phân đoạn này được phân tách bằng /. Các phân đoạn có thể chứa ký tự đại diện *: chuỗi này khớp với mọi chuỗi con trong phân đoạn đường dẫn (ngay cả chuỗi con trống), ngoại trừ dấu phân tách thư mục /. Bạn có thể sử dụng ký tự đại diện này nhiều lần trong một phân đoạn đường dẫn. Ngoài ra, ký tự đại diện ** có thể khớp với các phân đoạn đường dẫn hoàn chỉnh hoặc không, nhưng phải khai báo dưới dạng một phân đoạn đường dẫn độc lập.

Ví dụ:
  • foo/bar.txt khớp chính xác với tệp foo/bar.txt trong gói này
  • foo/*.txt khớp với mọi tệp trong thư mục foo/ nếu tệp kết thúc bằng .txt (trừ khi foo/ là một gói con)
  • foo/a*.htm* khớp với mọi tệp trong thư mục foo/ bắt đầu bằng a, sau đó có một chuỗi tuỳ ý (có thể để trống), có .htm và kết thúc bằng một chuỗi tuỳ ý khác; chẳng hạn như foo/axx.htmfoo/a.html hoặc foo/axxx.html
  • **/a.txt khớp với mọi tệp a.txt trong mọi thư mục con của gói này
  • **/bar/**/*.txt khớp với mọi tệp .txt trong mọi thư mục con của gói này, nếu có ít nhất một thư mục trên đường dẫn kết quả được gọi là bar, chẳng hạn như xxx/bar/yyy/zzz/a.txt hoặc bar/a.txt (hãy nhớ rằng ** cũng khớp với 0 phân đoạn) hoặc bar/zzz/a.txt
  • ** khớp với mọi tệp trong mọi thư mục con của gói này
  • foo**/a.txt là một mẫu không hợp lệ, vì ** phải độc lập dưới dạng một phân khúc

Nếu đối số exclude_directories được bật (được đặt thành 1), các tệp của thư mục loại sẽ bị bỏ qua trong kết quả (mặc định 1).

Nếu đối số allow_empty được đặt thành False, hàm glob sẽ bị lỗi nếu kết quả không phải là danh sách trống.

Có một số điểm hạn chế và cảnh báo quan trọng:

  1. glob() chạy trong quá trình đánh giá tệp BUILD, nên glob() chỉ so khớp các tệp trong cây nguồn của bạn, không bao giờ tạo tệp. Nếu đang tạo một mục tiêu yêu cầu cả tệp nguồn và tệp tạo, bạn phải thêm danh sách rõ ràng các tệp được tạo vào tệp globic. Hãy xem ví dụ bên dưới về :mylib:gen_java_srcs.

  2. Nếu một quy tắc có cùng tên với một tệp nguồn được so khớp, thì quy tắc đó sẽ "shadow" tệp đó.

    Để hiểu được điều này, hãy nhớ rằng glob() trả về danh sách các đường dẫn, vì vậy, việc sử dụng glob() trong các quy tắc khác#39; thuộc tính (ví dụ: srcs = glob(["*.cc"])) có tác dụng tương tự như việc liệt kê các đường dẫn được so khớp một cách rõ ràng. Ví dụ: nếu glob() tạo ra ["Foo.java", "bar/Baz.java"] nhưng cũng có một quy tắc trong gói có tên "Foo.java" (được phép, mặc dù Bazel đã cảnh báo về điều này), thì trình thu thập dữ liệu của glob() sẽ sử dụng "Foo.java" quy tắc (kết quả của nó) thay vì tệp "Foo.java" Xem lỗi GitHub #10395 để biết thêm thông tin chi tiết.

  3. Glob có thể khớp với các tệp trong thư mục con. Và tên thư mục con có thể được thay thế bằng ký tự đại diện. Tuy nhiên...
  4. Nhãn không được phép vượt ra ngoài ranh giới của gói và glob không khớp với các tệp trong gói con.

    Ví dụ: biểu thức glob **/*.cc trong gói x không bao gồm x/y/z.cc nếu x/y tồn tại dưới dạng một gói (dưới dạng x/y/BUILD hoặc một nơi khác trên đường dẫn gói). Điều này có nghĩa là kết quả của biểu thức glob thực sự phụ thuộc vào sự tồn tại của các tệp BUILD — nghĩa là cùng một biểu thức glob sẽ bao gồm x/y/z.cc nếu không có gói nào được gọi là x/y hoặc được đánh dấu là đã xóa bằng cách sử dụng cờ --delete_packages.

  5. Quy định hạn chế nêu trên áp dụng cho tất cả biểu thức glob, bất kể ký tự đại diện đó sử dụng ký tự đại diện nào.
  6. Một tệp ẩn có tên tệp bắt đầu bằng . sẽ khớp hoàn toàn với cả ký tự đại diện ***. Nếu bạn muốn khớp một tệp ẩn với mẫu phức hợp, mẫu của bạn cần bắt đầu bằng .. Ví dụ: *.*.txt sẽ khớp với .foo.txt, nhưng *.txt sẽ không khớp. Các thư mục bị ẩn cũng được so khớp theo cách tương tự. Các thư mục bị ẩn có thể bao gồm các tệp không bắt buộc làm dữ liệu đầu vào và có thể làm tăng số lượng tệp bị lỗi không cần thiết cũng như mức tiêu thụ bộ nhớ. Để loại trừ các thư mục bị ẩn, hãy thêm các thư mục đó vào đối số danh sách "excluded".
  7. "**" ký tự đại diện có một trường hợp góc: mẫu "**" không khớp với đường dẫn thư mục của gói\39;. Điều này có nghĩa là, glob(["**"], exclude_directories = 0) khớp với tất cả các tệp và thư mục một cách bắc cầu trong thư mục của gói hiện tại (nhưng tất nhiên là không đi vào các thư mục của gói con – hãy xem ghi chú trước đó về vấn đề này).

Nhìn chung, bạn nên cố gắng cung cấp một phần mở rộng thích hợp (ví dụ: *.html) thay vì sử dụng mã #39;*#39; cho một mẫu hình cầu. Tên rõ ràng hơn là vừa tự ghi lại và đảm bảo rằng bạn không vô tình khớp các tệp sao lưu hoặc tệp tự động lưu emacs/vi/....

Khi viết các quy tắc xây dựng, bạn có thể liệt kê các thành phần của hình cầu. Điều này cho phép tạo quy tắc riêng cho mọi dữ liệu nhập, ví dụ: Xem nội dung ví dụ về hình ảnh mở rộng ở bên dưới.

Ví dụ về Glob

Tạo một thư viện Java được xây dựng từ tất cả các tệp java trong thư mục này và tất cả các tệp do quy tắc :gen_java_srcs tạo.

java_library(
    name = "mylib",
    srcs = glob(["*.java"]) + [":gen_java_srcs"],
    deps = "...",
)

genrule(
    name = "gen_java_srcs",
    outs = [
        "Foo.java",
        "Bar.java",
    ],
    ...
)

Bao gồm tất cả tệp txt trong kiểm thử thư mục dữ liệu, ngoại trừ Experiment.txt. Lưu ý rằng các tệp trong thư mục con của dữ liệu kiểm thử sẽ không được đưa vào. Nếu bạn muốn đưa các tệp đó vào, hãy sử dụng tính năng định kỳ (globic glober) (**).

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(
        ["testdata/*.txt"],
        exclude = ["testdata/experimental.txt"],
    ),
)

Ví dụ về Glob đệ quy

Để quá trình kiểm thử phụ thuộc vào tất cả tệp txt trong thư mục kiểm thử dữ liệu và mọi thư mục con của thư mục đó (và các thư mục con của các tệp đó, v.v.). Các thư mục con chứa tệp BUILD sẽ bị bỏ qua. (Xem các giới hạn và cảnh báo ở trên.)

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(["testdata/**/*.txt"]),
)

Tạo một thư viện được xây dựng từ tất cả các tệp java trong thư mục này và tất cả thư mục con, ngoại trừ những thư mục có đường dẫn bao gồm một thư mục có tên kiểm thử. Bạn nên tránh sử dụng mẫu này nếu có thể, vì việc này có thể làm tăng mức độ tăng dần của bản dựng, từ đó tăng thời gian tạo bản dựng.

java_library(
    name = "mylib",
    srcs = glob(
        ["**/*.java"],
        exclude = ["**/testing/**"],
    ),
)

Ví dụ về Glob mở rộng

Tạo một quy tắc gen riêng cho *_test.cc trong thư mục hiện tại tính số dòng trong tệp.

# Conveniently, the build language supports list comprehensions.
[genrule(
    name = "count_lines_" + f[:-3],  # strip ".cc"
    srcs = [f],
    outs = ["%s-linecount.txt" % f[:-3]],
    cmd = "wc -l $< >$@",
 ) for f in glob(["*_test.cc"])]

Nếu tệp BUILD ở trên nằm trong gói //foo và gói chứa ba tệp phù hợp, a_test.cc, b_test.cc và c_test.cc thì việc chạy bazel query '//foo:all' sẽ liệt kê tất cả các quy tắc đã được tạo:

$ bazel query '//foo:all' | sort
//foo:count_lines_a_test
//foo:count_lines_b_test
//foo:count_lines_c_test

chọn

select(
    {conditionA: valuesA, conditionB: valuesB, ...},
    no_match_error = "custom message"
)

select() là hàm trợ giúp giúp tạo một thuộc tính quy tắc có thể định cấu hình. Hàm này có thể thay thế cho phần bên phải của gần như mọi mục chỉ định thuộc tính để giá trị của thuộc tính đó phụ thuộc vào cờ Bazel của dòng lệnh. Ví dụ: bạn có thể sử dụng tính năng này để xác định các phần phụ thuộc cụ thể cho nền tảng hoặc để nhúng các tài nguyên khác nhau tùy thuộc vào việc quy tắc được xây dựng ở chế độ "developer" so với "release".

Cách sử dụng cơ bản như sau:

sh_binary(
    name = "mytarget",
    srcs = select({
        ":conditionA": ["mytarget_a.sh"],
        ":conditionB": ["mytarget_b.sh"],
        "//conditions:default": ["mytarget_default.sh"]
    })
)

Điều này giúp thuộc tính srcs của sh_binary có thể định cấu hình bằng cách thay thế danh sách nhãn thông thường của thuộc tính đó bằng một lệnh gọi select liên kết các điều kiện cấu hình với các giá trị phù hợp. Mỗi điều kiện là một tham chiếu nhãn tới config_setting hoặc constraint_value, "khớp" nếu cấu hình mục tiêu khớp với một tập hợp giá trị dự kiến. Sau đó, giá trị của mytarget#srcs sẽ trở thành bất kỳ danh sách nhãn nào khớp với lệnh gọi hiện tại.

Lưu ý:

  • Chỉ chọn một điều kiện cho mỗi lệnh gọi.
  • Nếu nhiều điều kiện khớp và một điều kiện là chuyên môn của các điều kiện khác, thì chuyên môn sẽ được ưu tiên. Điều kiện B được coi là chuyên môn về điều kiện A nếu B có tất cả cờ và giá trị ràng buộc giống như A cộng với một số cờ hoặc giá trị ràng buộc bổ sung. Điều này cũng có nghĩa là độ phân giải chuyên biệt không được thiết kế để tạo thứ tự như ví dụ 2 dưới đây.
  • Nếu có nhiều điều kiện khớp với nhau và một điều kiện không phải là chuyên môn của tất cả các điều kiện khác, thì Bazel sẽ không xử lý được lỗi.
  • Nhãn giả đặc biệt //conditions:default được coi là khớp nếu không có điều kiện nào khác khớp. Nếu điều kiện này bị bỏ sót, một số quy tắc khác phải khớp để tránh lỗi.
  • Bạn có thể nhúng select bên trong một thuộc tính lớn hơn. Vì vậy, srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...}) srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]}) là các biểu thức hợp lệ.
  • select hoạt động với hầu hết (nhưng không phải tất cả) thuộc tính. Các thuộc tính không tương thích được đánh dấu là nonconfigurable trong tài liệu.

    gói con

    subpackages(include, exclude=[], allow_empty=True)

    subpackages() là một hàm trợ giúp, tương tự như glob() liệt kê các gói con thay vì các tệp và thư mục. Tệp này sử dụng cùng một mẫu đường dẫn như glob() và có thể khớp với bất kỳ gói con nào là phần tử con trực tiếp của tệp BUILD hiện đang tải. Hãy xem nội dung glob để biết nội dung giải thích chi tiết và các ví dụ về các mẫu bao gồm và loại trừ.

    Danh sách kết quả của các gói con được trả về nằm theo thứ tự sắp xếp và chứa các đường dẫn liên quan đến gói tải hiện tại khớp với mẫu nhất định trong include và không khớp với các mẫu trong exclude.

    Ví dụ:

    Ví dụ sau đây liệt kê tất cả các gói con trực tiếp của gói foo/BUILD

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs = subpackages(include = ["**"])
    
    # results in subs == ["sub", "bar/baz"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    

    Nhìn chung, thay vì gọi trực tiếp hàm này, người dùng sẽ sử dụng mô-đun "#39;subpackages" #39; của skylib.