Nhãn là giá trị nhận dạng cho một mục tiêu. Một nhãn thông thường ở dạng chuẩn đầy đủ sẽ có dạng như sau:
@@myrepo//my/app/main:app_binary
Phần đầu tiên của nhãn là tên kho lưu trữ, @@myrepo
. Cú pháp @
gấp đôi cho biết đây là tên repo chính tắc, duy nhất trong không gian làm việc. Nhãn có tên kho lưu trữ chuẩn sẽ xác định mục tiêu một cách rõ ràng
bất kể chúng xuất hiện trong bối cảnh nào.
Thường thì tên kho lưu trữ chính tắc là một chuỗi bí ẩn có dạng như @@rules_java~7.1.0~toolchains~local_jdk
. Thông thường, bạn sẽ thấy các nhãn có tên kho lưu trữ rõ ràng, như sau:
@myrepo//my/app/main:app_binary
Điểm khác biệt duy nhất là tên kho lưu trữ có tiền tố @
thay vì 2.
Đây là một kho lưu trữ có tên rõ ràng là myrepo
, có thể khác
dựa trên ngữ cảnh xuất hiện của nhãn này.
Trong trường hợp thông thường, nhãn tham chiếu đến cùng một kho lưu trữ mà từ đó
nó được sử dụng, thì phần tên kho lưu trữ có thể bị bỏ qua. Vì vậy, bên trong @@myrepo
, phần đầu tiên
nhãn thường được viết là
//my/app/main:app_binary
Phần thứ hai của nhãn là tên gói không đủ điều kiện
my/app/main
, đường dẫn đến gói
so với gốc của kho lưu trữ. Đồng thời, tên kho lưu trữ và
tên gói chưa đủ điều kiện tạo thành tên gói đủ điều kiện
@@myrepo//my/app/main
. Khi nhãn tham chiếu đến cùng một gói mà nhãn đó được sử dụng, bạn có thể bỏ qua tên gói (và dấu hai chấm nếu muốn). Vì vậy, bên trong @@myrepo//my/app/main
,
bạn có thể ghi nhãn này theo một trong các cách sau:
app_binary
:app_binary
Theo quy ước, dấu hai chấm sẽ bị bỏ qua đối với tệp nhưng được giữ lại đối với quy tắc. Tuy nhiên, điều này không quan trọng.
Phần của nhãn sau dấu hai chấm, app_binary
là tên mục tiêu không đủ điều kiện. Khi khớp với thành phần cuối cùng của đường dẫn gói, bạn có thể bỏ qua thành phần này và dấu hai chấm. Vì vậy, hai nhãn này tương đương với nhau:
//my/app/lib
//my/app/lib:lib
Tên của mục tiêu tệp trong thư mục con của gói là đường dẫn của tệp
so với thư mục gốc của gói (thư mục chứa tệp BUILD
). Vì vậy,
tệp này nằm trong thư mục con my/app/main/testdata
của kho lưu trữ:
//my/app/main:testdata/input.txt
Các chuỗi như //my/app
và @@some_repo//my/app
có hai ý nghĩa tuỳ thuộc vào
ngữ cảnh sử dụng: khi Bazel mong đợi một nhãn, ý nghĩa của các từ khoá đó
//my/app:app
và @@some_repo//my/app:app
. Nhưng, khi Bazel
mong đợi một gói (ví dụ: trong thông số kỹ thuật package_group
), chúng tham chiếu đến
gói chứa nhãn đó.
Một lỗi thường gặp trong tệp BUILD
là sử dụng //my/app
để tham chiếu đến một gói hoặc tất cả mục tiêu trong một gói. Hãy nhớ rằng, thuộc tính này tương đương với //my/app:app
, vì vậy, thuộc tính này sẽ đặt tên cho mục tiêu app
trong gói my/app
của kho lưu trữ hiện tại.
Tuy nhiên, bạn nên sử dụng //my/app
để tham chiếu đến một gói trong thông số kỹ thuật của package_group
hoặc trong tệp .bzl
, vì thông số này cho biết rõ tên gói là tuyệt đối và bắt nguồn từ thư mục cấp cao nhất của không gian làm việc.
Bạn không thể sử dụng nhãn tương đối để tham chiếu đến các mục tiêu trong các gói khác; bạn phải luôn chỉ định giá trị nhận dạng kho lưu trữ và tên gói trong trường hợp này.
Ví dụ: nếu cây nguồn chứa cả gói my/app
và
gói my/app/testdata
(mỗi thư mục trong số hai thư mục này có một gói riêng
BUILD
), gói sau chứa một tệp có tên testdepot.zip
. Ở đây
là hai cách (một sai, một đúng) để tham chiếu đến tệp này trong
//my/app:BUILD
:
Sai – testdata
là một gói khác, vì vậy, bạn không thể sử dụng đường dẫn tương đối
testdata/testdepot.zip
Đúng — tham chiếu đến testdata
với đường dẫn đầy đủ
//my/app/testdata:testdepot.zip
Các nhãn bắt đầu bằng @@//
là các tệp tham chiếu đến kho lưu trữ chính. Các tệp này vẫn hoạt động ngay cả từ các kho lưu trữ bên ngoài.
Do đó, @@//a/b/c
khác với
//a/b/c
khi được tham chiếu từ một kho lưu trữ bên ngoài.
Phương thức trước tham chiếu lại kho lưu trữ chính, trong khi phương thức sau tìm //a/b/c
trong chính kho lưu trữ bên ngoài.
Điều này đặc biệt phù hợp khi viết các quy tắc trong kho lưu trữ chính tham chiếu đến các mục tiêu trong kho lưu trữ chính và sẽ được sử dụng từ các kho lưu trữ bên ngoài.
Để biết thông tin về các cách khác nhau mà bạn có thể tham chiếu đến mục tiêu, hãy xem mẫu mục tiêu.
Quy cách từ vựng của nhãn
Cú pháp nhãn không khuyến khích sử dụng siêu ký tự có ý nghĩa đặc biệt đối với shell. Điều này giúp tránh các vấn đề trích dẫn do vô tình, đồng thời giúp bạn dễ dàng tạo các công cụ và tập lệnh để thao tác với nhãn, chẳng hạn như Ngôn ngữ truy vấn Bazel.
Dưới đây là thông tin chi tiết chính xác về các tên mục tiêu được phép.
Tên mục tiêu — package-name:target-name
target-name
là tên của mục tiêu trong gói. Tên của quy tắc là giá trị của thuộc tính name
trong phần khai báo của quy tắc trong tệp BUILD
; tên của tệp là đường dẫn tương ứng với thư mục chứa tệp BUILD
.
Tên mục tiêu phải bao gồm toàn bộ các ký tự được lấy từ nhóm a
– z
,
A
– Z
, 0
– 9
và các ký hiệu dấu câu !%-@^_"#$&'()*-+,;<=>?[]{|}~/.
.
Tên tệp phải là tên đường dẫn tương đối ở dạng thông thường, nghĩa là tên phải
không bắt đầu và kết thúc bằng dấu gạch chéo (ví dụ: /foo
và foo/
là
cấm) cũng như không chứa nhiều dấu gạch chéo liên tiếp dưới dạng dấu phân cách đường dẫn
(ví dụ: foo//bar
). Tương tự, các tệp đối chiếu cấp cao (..
) và
các tham chiếu đến thư mục hiện tại (./
) bị cấm.
Sai — Không sử dụng..` để tham chiếu đến các tệp trong các gói khác
Đúng – Sử dụng `//package-name:filename`
Mặc dù mọi người thường sử dụng /
khi đặt tên cho mục tiêu tệp, nhưng bạn nên tránh sử dụng
/
trong tên quy tắc. Đặc biệt là khi sử dụng dạng viết tắt của nhãn, điều này có thể gây nhầm lẫn cho người đọc. Nhãn //foo/bar/wiz
luôn là viết tắt
cho //foo/bar/wiz:wiz
, ngay cả khi không có gói nào như vậy foo/bar/wiz
; nó
không bao giờ tham chiếu đến //foo:bar/wiz
, ngay cả khi mục tiêu đó tồn tại.
Tuy nhiên, có một số trường hợp mà việc sử dụng dấu gạch chéo thuận tiện hoặc đôi khi thậm chí cần thiết. Ví dụ: tên của một số quy tắc nhất định phải khớp với tệp nguồn chính của quy tắc đó. Tệp nguồn chính có thể nằm trong một thư mục con của gói.
Tên gói — //package-name:target-name
Tên của một gói là tên của thư mục chứa tệp BUILD
, tương ứng với thư mục cấp cao nhất của kho lưu trữ chứa gói đó.
Ví dụ: my/app
.
Tên gói phải bao gồm toàn bộ ký tự được lấy từ tập hợp A
-Z
, a
–z
, 0
–9
, "/
", "-
", ".
", "@
" và "_
", đồng thời không được bắt đầu bằng dấu gạch chéo.
Đối với một ngôn ngữ có cấu trúc thư mục quan trọng đối với hệ thống mô-đun (ví dụ: Java), điều quan trọng là bạn phải chọn tên thư mục là giá trị nhận dạng hợp lệ trong ngôn ngữ đó.
Mặc dù Bazel hỗ trợ các mục tiêu trong gói gốc của không gian làm việc (ví dụ: //:foo
), tốt nhất bạn nên để trống gói đó để tất cả các gói có ý nghĩa đều có tên mô tả.
Tên gói không được chứa chuỗi con //
và không được kết thúc bằng dấu gạch chéo.
Quy tắc
Quy tắc chỉ định mối quan hệ giữa dữ liệu đầu vào và đầu ra, cũng như các bước để tạo dữ liệu đầu ra. Quy tắc có thể là một trong nhiều quy tắc loại (đôi khi được gọi là lớp quy tắc), lớp này tạo ra tệp thực thi và thư viện, tệp thực thi kiểm thử và các tệp thực thi khác được hỗ trợ kết quả như mô tả trong Xây dựng Bách khoa toàn thư.
Tệp BUILD
khai báo mục tiêu bằng cách gọi quy tắc.
Trong ví dụ bên dưới, chúng ta thấy nội dung khai báo của mục tiêu my_app
bằng quy tắc cc_binary
.
cc_binary(
name = "my_app",
srcs = ["my_app.cc"],
deps = [
"//absl/base",
"//absl/strings",
],
)
Mỗi lệnh gọi quy tắc đều có một thuộc tính name
(phải là một thuộc tính hợp lệ
target name), khai báo mục tiêu trong gói
của tệp BUILD
.
Mỗi quy tắc đều có một tập hợp các thuộc tính; các thuộc tính có thể áp dụng cho một thuộc tính nhất định và tầm quan trọng và ngữ nghĩa của mỗi thuộc tính là một hàm của loại quy tắc; hãy xem nội dung Xây dựng Bách khoa toàn thư để biết danh sách quy tắc và thuộc tính tương ứng của chúng. Mỗi thuộc tính đều có tên và một loại. Một số loại phổ biến của một thuộc tính là số nguyên, nhãn, danh sách of label (nhãn), string (chuỗi), danh sách chuỗi (Output), output (nhãn đầu ra), danh sách các nhãn đầu ra. Không phải thuộc tính nào cũng cần được chỉ định trong mọi quy tắc. Do đó, các thuộc tính tạo thành từ điển từ khoá (tên) thành giá trị đã nhập tuỳ chọn.
Thuộc tính srcs
có trong nhiều quy tắc có loại "danh sách nhãn"; giá trị của thuộc tính này (nếu có) là một danh sách nhãn, mỗi nhãn là tên của một mục tiêu là dữ liệu đầu vào cho quy tắc này.
Trong một số trường hợp, tên của loại quy tắc có phần tuỳ ý và thú vị hơn là tên của các tệp do quy tắc tạo ra, và điều này đúng với genrules. Để biết thêm thông tin, hãy xem Quy tắc chung: quy tắc gen.
Trong các trường hợp khác, tên có ý nghĩa quan trọng: ví dụ: đối với các quy tắc *_binary
và *_test
, tên quy tắc xác định tên của tệp thực thi do bản dựng tạo ra.
Biểu đồ không tuần hoàn có hướng này trên các mục tiêu được gọi là biểu đồ mục tiêu hoặc biểu đồ phần phụ thuộc bản dựng và là miền mà Công cụ truy vấn Bazel hoạt động.
Mục tiêu | BUILD files |