Nhãn

Báo cáo vấn đề Xem nguồn Hằng đêm · 7,3 · 7,2 · 7.1 · 7 · 6,5

Nhãn là giá trị nhận dạng của một mục tiêu. Một nhãn điển hình trong trang chính tắc đầy đủ 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. Kép @ cú pháp biểu thị rằng đây là một kho lưu trữ chính tắc name (tên 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ường, tên kho lưu trữ chuẩn là một chuỗi arcane có dạng như @@rules_java++toolchains+local_jdk. Thông tin thường thấy hơn các nhãn có tên kho lưu trữ rõ ràng, mã sẽ có dạ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 đề cập đến cùng một gói mà nó được sử dụng trong, tên gói (và không bắt buộc có dấu hai chấm) có thể bị bỏ qua. 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 bị bỏ qua đối với tệp, nhưng được giữ lại theo quy tắc nhưng không đáng kể.

Phần nhãn nằm sau dấu hai chấm, app_binary là 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, phần tử và dấu hai chấm, có thể được bỏ qua. 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@@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@@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 các tệp BUILD là dùng //my/app để tham chiếu đến một gói, hoặc cho tất cả mục tiêu trong một gói chứ không phải. Hãy nhớ rằng, tương đương với //my/app:app, nên sẽ đặt tên cho mục tiêu app trong my/app gói 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 đặc tả của package_group hoặc trong tệp .bzl, vì rõ ràng cho biết tên gói là tuyệt đối và đã bị can thiệp vào hệ thống ở cấp cao nhất của không gian làm việc.

Không thể dùng nhãn tương đối để tham chiếu đến mục tiêu trong các gói khác; thời gian 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:

Saitestdata 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

Nhãn bắt đầu bằng @@// là tham chiếu đến biến kho lưu trữ này vẫn sẽ 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ần trước tham chiếu về kho lưu trữ chính, còn phần sau tham chiếu đến kho lưu trữ chính tìm //a/b/c trong chính kho lưu trữ bên ngoài. Điều này đặc biệt liên quan khi viết các quy tắc trong kho lưu trữ tham chiếu đến các mục tiêu trong kho lưu trữ chính và sẽ là đượ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 một 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 vỏ. Điều này giúp tránh việc vô tình trích dẫn và giúp người dùng dễ dàng tạo các công cụ và tập lệnh thao túng 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 BUILD file; tên của tệp là tên đườ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 az, AZ, 09 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ụ: /foofoo/ 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 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 khi dạng viết tắt của nhãn là nên có thể khiến người đọc nhầm lẫn. 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 các quy tắc nhất định phải khớp với tệp nguồn chính của gói. Tệp này có thể nằm trong 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, so với thư mục cấp cao nhất của kho lưu trữ chứa. Ví dụ: my/app.

Ở cấp độ kỹ thuật, Bazel thực thi những việc sau:

  • Ký tự được phép trong tên gói là các chữ cái viết thường từ a đến z, chữ cái viết hoa A đến Z, các chữ số từ 0 đến 9, ký tự ! \"#$%&'()*+,-.;<=>?@[]^_`{|} (có, có một ký tự dấu cách ở đó!), và dĩ nhiên là dấu gạch chéo lên / (vì đó là thư mục dòng phân cách).
  • Tên gói không được bắt đầu hoặc kết thúc bằng ký tự dấu gạch chéo lên /.
  • Tên gói không được chứa chuỗi con //. Điều này sẽ không giúp ý nghĩa---đường dẫn thư mục tương ứng là gì?
  • Tên gói không được chứa chuỗi con /./, /../ hoặc /.../, v.v. Việc thực thi này được thực hiện để tránh nhầm lẫn khi chuyển đổi giữa một đoạn mã logic tên gói và tên thư mục thực, dựa vào ý nghĩa ngữ nghĩa của ký tự dấu chấm trong chuỗi đường dẫn.

Trên thực tế:

  • Đối với ngôn ngữ có cấu trúc thư mục quan trọng đối với mô-đun của ngôn ngữ đó hệ thống của mình (ví dụ: Java), thì bạn cần phải chọn tên thư mục giá trị nhận dạng hợp lệ trong ngôn ngữ. Ví dụ: Đừng bắt đầu bằng và tránh các ký tự đặc biệt, đặc biệt là dấu gạch dưới và dấu gạch nối.
  • 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), bạn nên để trống gói đó để tất cả các gói có ý nghĩa có tên mô tả.

Quy tắc

Quy tắc chỉ định mối quan hệ giữa đầu vào và đầu ra, và các bước tạo đầ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 phần khai báo về my_app mục tiêu bằng cách sử dụ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 cần phải đượ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"; của (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 đầ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 hơi tuỳ ý, thú vị là tên của các tệp được tạo bởi quy tắc và điều này đúng 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 này có ý nghĩa: đối với các quy tắc *_binary*_test, ví dụ: tên quy tắc xác định tên của tệp thực thi được tạo bởi bản dựng.

Đồ thị không chu trình có hướng 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 của bản dựng và là miền mà qua đó Công cụ truy vấn Bazel hoạt động.

Mục tiêu XÂY DỰNG tệp