Nội dung
gói hàng
package(default_deprecation, default_package_metadata, 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 trong gói. Tệp này được sử dụng tối đa một lần trong một gói (tệp BUILD).
Đối với phần đối ứng khai báo siêu dữ liệu áp dụng cho mọi quy tắc trong toàn bộ kho lưu trữ, hãy sử dụng hàm repo()
trong tệp REPO.bazel
ở thư mục gốc của kho lưu trữ.
Hàm repo()
có các đối số giống hệt như package()
.
Bạn nên gọi hàm package() ngay sau tất cả các câu lệnh load() ở đầu tệp, trước mọi quy tắc.
Đối số
Thuộc tính | Mô tả |
---|---|
default_applicable_licenses |
Bí danh của |
default_visibility |
Danh sách nhãn; mặc định là 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ừ phi có quy định khác trong thuộc tính |
default_deprecation |
Chuỗi; giá trị mặc định là Đặt thông báo |
default_package_metadata |
Danh sách nhãn; mặc định là Đặt danh sách mặc định gồm các mục tiêu siêu dữ liệu áp dụng cho tất cả các mục tiêu khác trong gói. Đây thường là các mục tiêu liên quan đến gói OSS và nội dung khai báo giấy phép. Hãy xem rules_license để biết ví dụ. |
default_testonly |
Boolean; mặc định là Đặt thuộc tính
Trong các gói thuộc |
features |
Danh sách chuỗi; mặc định là Đặ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ý theo cách đặc biệt. Đừng sử dụng tính năng này trừ phi có người làm việc trên hệ thống xây dựng yêu cầu rõ rà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ị với các thành viên của nhóm gói//foo:target
. Các nội dung khai báo chế độ hiển thị riêng lẻ trên một quy tắc (nếu có) sẽ ghi đè thông số kỹ thuật này.
package(default_visibility = ["//foo:target"])
package_group
package_group(name, packages, includes)
Hàm này xác định một tập hợp các gói và liên kết nhãn với tập hợp đó. Bạn có thể tham chiếu nhãn trong các thuộc tính visibility
.
Các nhóm gói chủ yếu được 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. Một mục tiêu hiển thị riêng tư chỉ có thể được tham chiếu trong gói riêng của nó (không phải gói con). Giữa các trường hợp này, mục tiêu có thể cho phép truy cập vào gói riêng của mình cùng với bất kỳ gói nào mà một hoặc nhiều nhóm gói mô tả. Để biết 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 chế độ hiển thị.
Một gói nhất định được coi là nằm trong nhóm nếu 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 về mặt kỹ thuật nhưng không được tạo theo quy tắc và không có biện pháp bảo vệ chế độ hiển thị nào.
Đối số
Thuộc tính | Mô tả |
---|---|
name |
Tên; bắt buộc Tên duy nhất cho mục tiêu này. |
packages |
Danh sách chuỗi; mặc định là Danh sách có thể trống hoặc có một hoặc nhiều thông số kỹ thuật của gói. Mỗi chuỗi thông số kỹ thuật của gói có thể có một trong các dạng sau:
Ngoài ra, hai kiểu thông số kỹ thuật đầu tiên của gói cũng có thể được thêm tiền tố Nhóm gói chứa bất kỳ gói nào phù hợp với ít nhất một trong các thông số kỹ thuật dương của nhóm và không có thông số kỹ thuật tiêu cực nào của nhóm. Ví dụ: giá trị 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, thì việc này cũng giống như việc đặt thuộc tính này thành danh sách trống, cũng giống như việc đặt thuộc tính này thành danh sách chỉ chứa Lưu ý: Trước Bazel 6.0, quy cách Lưu ý: Trước Bazel 6.0, khi thuộc tính này được chuyển đổi tuần tự dưới dạng một phần của |
includes |
Danh sách nhãn; mặc định là Các nhóm gói khác có trong nhóm này. 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 nhóm gói được tham chiếu được coi là một phần của nhóm gói này. Đây là mang tính bắc cầu – nếu nhóm gói Khi sử dụng cùng với thông số kỹ thuật gói bị phủ định, hãy lưu ý rằng trước tiên, tập hợp các gói cho mỗi nhóm được tính toán độc lập và sau đó kết hợp các kết quả với nhau. Điều này có nghĩa là các thông số kỹ thuật bị phủ định trong một nhóm không ảnh hưởng đến các thông số kỹ thuật trong một nhóm khác. |
Ví dụ
Nội dung khai báo package_group
sau đây chỉ định một nhóm gói có tên là "nhiệt đới" 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 đây chỉ định các nhóm gói của một ứng dụng giả định:
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"], )
exports_files
exports_files([label, ...], visibility, licenses)
exports_files()
chỉ định danh sách các tệp thuộc gói này và đượ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 những tệp đó được xuất rõ ràng bằng câu lệnh exports_files()
. Đọc thêm về khả năng hiển thị của tệp.
Theo một hành vi cũ, các tệp được đề cập là dữ liệu đầu vào cho 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 ngược. Tuy nhiên, bạn không nên dựa vào hành vi này và chủ động di chuyển khỏi hành vi này.
Đối số
Đối số này 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 chế độ hiển thị; trong trường hợp này, tệp sẽ hiển thị cho các mục tiêu được chỉ định. Nếu bạn không chỉ định chế độ hiển thị, thì mọi gói đều sẽ thấy các tệp, ngay cả khi bạn đã chỉ định chế độ hiển thị mặc định của gói trong hàm package
. Bạn cũng có thể chỉ định giấy phép.
Ví dụ:
Ví dụ sau đây 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"])
glob
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ề một danh sách đường dẫn mới, có thể thay đổi và đượ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 đã tạo hay các mục tiêu khác).
Nhãn của tệp nguồn sẽ được đưa vào kết quả nếu đường dẫn tương đối của gói trong tệp khớp với bất kỳ mẫu include
nào và không khớp với mẫu exclude
nào.
Danh sách include
và exclude
chứa các mẫu đường dẫn liên quan đến 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 *
: ký tự này khớp với bất kỳ chuỗi con nào trong phân đoạn đường dẫn (ngay cả chuỗi con trống), ngoại trừ dấu phân cá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 0 hoặc nhiều phân đoạn đường dẫn hoàn chỉnh, nhưng phải được khai báo là phân đoạn đường dẫn độc lập.
foo/bar.txt
khớp chính xác với tệpfoo/bar.txt
trong gói nàyfoo/*.txt
khớp với mọi tệp trong thư mụcfoo/
nếu tệp đó kết thúc bằng.txt
(trừ phifoo/
là gói con)foo/a*.htm*
khớp với mọi tệp trong thư mụcfoo/
bắt đầu bằnga
, sau đó có một chuỗi tuỳ ý (có thể để trống), sau đó có.htm
và kết thúc bằng một chuỗi tuỳ ý khác; chẳng hạn nhưfoo/axx.htm
vàfoo/a.html
hoặcfoo/axxx.html
**/a.txt
khớp với mọi tệpa.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 í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ặcbar/a.txt
(hãy lưu ý rằng**
cũng khớp với các phân đoạn 0) hoặcbar/zzz/a.txt
**
khớp với mọi tệp trong mọi thư mục con của gói nàyfoo**/a.txt
là mẫu không hợp lệ vì**
phải đứng riêng như một phân đoạn
Nếu bạn bật đối số exclude_directories
(đặt thành 1), các tệp thuộc loại thư mục sẽ bị bỏ qua khỏi kết quả (mặc định là 1).
Nếu đối số allow_empty
được đặt thành False
, thì hàm glob
sẽ báo lỗi nếu kết quả là danh sách trống.
Có một số hạn chế và lưu ý quan trọng:
-
Vì
glob()
chạy trong quá trình đánh giá tệp BUILD, nênglob()
chỉ so khớp các tệp trong cây nguồn, không bao giờ so khớp các tệp đã tạo. Nếu đang tạo một mục tiêu yêu cầu cả tệp nguồn lẫn tệp được tạo, bạn phải thêm danh sách rõ ràng các tệp đã tạo vào khối cầu. Hãy xem ví dụ bên dưới với:mylib
và:gen_java_srcs
. -
Nếu một quy tắc có cùng tên với tệp nguồn được so khớp, thì quy tắc đó sẽ "che khuất" tệp.
Để hiểu đ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ụngglob()
trong thuộc tính của các quy tắc khác (ví dụ:srcs = glob(["*.cc"])
) cũng có tác dụng tương tự như việc liệt kê các đường dẫn khớp một cách rõ ràng. Ví dụ: nếuglob()
tạo ra["Foo.java", "bar/Baz.java"]
nhưng cũng có một quy tắc trong gói có tên là "Foo.java" (được phép, mặc dù Bazel cảnh báo về quy tắc này), thì người sử dụngglob()
sẽ sử dụng quy tắc "Foo.java" (kết quả đầu ra của quy tắc) thay vì tệp "Foo.java". Hãy xem vấn đề số 10395 trên GitHub để biết thêm thông tin chi tiết. - Glob có thể khớp với các tệp trong thư mục con. Đồng thời, tên thư mục con có thể được ký tự đại diện. Tuy nhiên...
-
Nhãn không được phép vượt qua ranh giới của gói và tệp toàn cầu sẽ không khớp với các tệp trong các gói con.
Ví dụ: biểu thức hình cầu
**/*.cc
trong góix
không bao gồmx/y/z.cc
nếux/y
tồn tại dưới dạng một gói (dưới dạngx/y/BUILD
hoặc một vị trí 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 toàn cầu thực sự phụ thuộc vào sự tồn tại của các tệp BUILD. Điều này có nghĩa là, biểu thức glob tương tự sẽ bao gồmx/y/z.cc
nếu không có gói nào được gọi làx/y
hoặc gói đó được đánh dấu là đã xoá bằng cờ --deleted_packages. - Quy định hạn chế ở trên áp dụng cho tất cả biểu thức glob, bất kể biểu thức đó sử dụng ký tự đại diện nào.
-
Một tệp ẩn có tên tệp bắt đầu bằng
.
hoàn toàn khớp với cả ký tự đại diện**
và*
. Nếu bạn muốn so khớp tệp ẩn với mẫu phức hợp, mẫu của bạn cần phải bắt đầu bằng.
. Ví dụ:*
và.*.txt
sẽ khớp với.foo.txt
, nhưng*.txt
thì không. Các thư mục ẩn cũng được so khớp theo cách tương tự. Các thư mục ẩ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 được gộp không cần thiết cũng như mức sử dụng bộ nhớ. Để loại trừ các thư mục ẩn, hãy thêm các thư mục đó vào đối số danh sách "exclude" (loại trừ). -
Ký tự đại diện "**" có một trường hợp đặc biệt: mẫu
"**"
không khớp với đường dẫn thư mục của gói. Điều này có nghĩa làglob(["**"], exclude_directories = 0)
khớp với mọi tệp và thư mục theo cách bắc cầu và nằm hoàn toàn trong thư mục của gói hiện tại (nhưng tất nhiên sẽ không đi vào thư mục của các gói con – hãy xem ghi chú trước về việc này).
Nói chung, bạn nên cố gắng cung cấp một đuôi tệp thích hợp (ví dụ: *.html) thay vì sử dụng dấu "*" trần cho mẫu glob. Tên càng rõ ràng thì càng tự ghi lại và đảm bảo rằng bạn không vô tình so 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 bản dựng, bạn có thể liệt kê các phần tử của khối cầu. Ví dụ: điều này cho phép tạo từng quy tắc cho mọi dữ liệu đầu vào. Hãy xem phần ví dụ về glob mở rộng bên dưới.
Ví dụ về ánh sáng loá
Tạo một thư viện Java được tạo 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", ], ... )
Thêm tất cả tệp txt vào thư mục testdata ngoại trừ experimental.txt. Xin lưu ý rằng các tệp trong thư mục con của testdata 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 hình cầu đệ quy (**).
sh_test( name = "mytest", srcs = ["mytest.sh"], data = glob( ["testdata/*.txt"], exclude = ["testdata/experimental.txt"], ), )
Ví dụ về vòng tròn đệ quy
Đặt kiểm thử phụ thuộc vào tất cả tệp txt trong thư mục testdata và bất kỳ thư mục con nào của thư mục đó (và các thư mục con của thư mục con đó, 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 tạo 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 là kiểm thử. Bạn nên tránh sử dụng mẫu này nếu có thể, vì mẫu này có thể làm giảm mức độ tăng dần của bản dựng, do đó làm tăng thời gian xây dựng.
java_library( name = "mylib", srcs = glob( ["**/*.java"], exclude = ["**/testing/**"], ), )
Ví dụ về băng thông rộng mở rộng
Tạo một quy tắc chung cho *_test.cc trong thư mục hiện tại để đếm 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 này chứa 3 tệp khớp là 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 đã 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 định cấu hình thuộc tính quy tắc.
Tệp này có thể thay thế phần bên phải của hầu hết mọi thao tác chỉ định thuộc tính, vì vậy giá trị của thuộc tính này phụ thuộc vào cờ Bazel 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 dành riêng cho nền tảng hoặc để nhúng nhiều tài nguyên tuỳ thuộc vào việc một quy tắc được tạo ở chế độ "nhà phát triển" hay "bản phát hành".
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"] }) )
Thao tác này giúp bạn có thể định cấu hình thuộc tính srcs
của sh_binary
bằng cách thay thế trạng thái gán danh sách nhãn thông thường bằng lệnh gọi select
ánh xạ các điều kiện cấu hình với các giá trị trùng khớp. Mỗi điều kiện là một nhãn tham chiếu đến config_setting
hoặc constraint_value
và sẽ "khớp" nếu cấu hình của 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ỉ một điều kiện được chọn trên 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ì điều kiện chuyên môn sẽ được ưu tiên. Điều kiện B được coi là chuyên môn của điều kiện A nếu B có tất cả các cờ và giá trị ràng buộc giống như A cộng thêm một số cờ hoặc giá trị ràng buộc bổ sung. Điều này cũng có nghĩa là quá trình phân giải chuyên biệt không được thiết kế để tạo thứ tự như minh hoạ trong Ví dụ 2 bên dưới.
- Nếu nhiều điều kiện khớp và một điều kiện không phải là chuyên biệt của tất cả các điều kiện khác, thì Bazel sẽ không thành công và báo lỗi, trừ khi tất cả các điều kiện đều phân giải thành cùng một giá trị.
- 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ỏ qua, một số quy tắc khác phải khớp để tránh xảy ra lỗi. - Bạn có thể nhúng
select
bên trong một chỉ định thuộc tính lớn hơn. Vì vậy,srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...})
vàsrcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]})
là biểu thức hợp lệ. select
hoạt động với hầu hết các thuộc tính, nhưng không phải tất cả. Các thuộc tính không tương thích được đánh dấu lànonconfigurable
trong tài liệu tương thích.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ì tệp và thư mục. Phương thức này sử dụng cùng một mẫu đường dẫn vớiglob()
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 đang tải. Bạn có thể xem phần glob để biết nội dung giải thích chi tiết cũng như ví dụ về các mẫu bao gồm và loại trừ.Danh sách các gói con được trả về 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 các mẫu đã cho trong
include
chứ không phải các đường dẫn trongexclude
.Ví dụ:
Ví dụ sau đây liệt kê tất cả các gói con trực tiếp cho 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, người dùng nên sử dụng mô-đun "subpackages" của skylib thay vì gọi trực tiếp hàm này.