Bazel hỗ trợ các phần phụ thuộc bên ngoài, các tệp nguồn (cả văn bản và tệp nhị phân) được sử dụng trong bản dựng không phải từ không gian làm việc của bạn. Ví dụ: đó có thể là một bộ quy tắc được lưu trữ trong một kho lưu trữ GitHub, một cấu phần phần mềm Maven hoặc một thư mục trên máy cục bộ bên ngoài không gian làm việc hiện tại của bạn.
Kể từ Bazel 6.0, có 2 cách để quản lý các phần phụ thuộc bên ngoài bằng Bazel: hệ thống WORKSPACE
truyền thống, tập trung vào kho lưu trữ và hệ thống MODULE.bazel
tập trung vào mô-đun mới hơn (có tên mã là Bzlmod và được bật bằng cờ --enable_bzlmod
). Hai hệ thống này có thể được sử dụng, nhưng Bzlmod sẽ thay thế hệ thống WORKSPACE
trong các bản phát hành Bazel trong tương lai, xem hướng dẫn di chuyển Bzmod cùng nhau.
Tài liệu này giải thích các khái niệm liên quan đến việc quản lý phần phụ thuộc bên ngoài trong Bazel, trước khi đi sâu vào chi tiết hơn về hai hệ thống theo thứ tự.
Khái niệm
Kho lưu trữ
Thư mục có tệp WORKSPACE
hoặc WORKSPACE.bazel
, chứa các tệp nguồn sẽ được dùng trong bản dựng Bazel. Thường được rút ngắn thành kho lưu trữ.
Kho lưu trữ chính
Kho lưu trữ đang chạy lệnh Bazel hiện tại.
Workspace
Môi trường dùng chung của tất cả các lệnh Bazel sẽ chạy trong cùng một kho lưu trữ chính.
Xin lưu ý rằng trước đây, các khái niệm "kho lưu trữ" và "không gian làm việc" đã bị lẫn lộn; thuật ngữ "không gian làm việc" thường được dùng để chỉ kho lưu trữ chính và đôi khi thậm chí còn được dùng làm từ đồng nghĩa của "kho lưu trữ".
Tên kho lưu trữ chuẩn
Tên chuẩn hoá của kho lưu trữ có thể định địa chỉ. Trong bối cảnh
không gian làm việc, mỗi kho lưu trữ có một tên chính tắc duy nhất. Bạn có thể nhắm mục tiêu bên trong một kho lưu trữ có tên chuẩn là canonical_name
bằng nhãn @@canonical_name//pac/kage:target
(lưu ý @
kép).
Kho lưu trữ chính luôn có chuỗi trống làm tên chuẩn.
Tên kho lưu trữ hiển thị
Tên của một kho lưu trữ có thể được định địa chỉ trong ngữ cảnh của một kho lưu trữ khác.
Đây có thể được coi là "biệt hiệu" của một kho lưu trữ: Kho lưu trữ có tên chuẩn michael
có thể có tên rõ ràng là mike
trong ngữ cảnh của kho lưu trữ alice
, nhưng có thể có tên rõ ràng là mickey
trong ngữ cảnh của kho lưu trữ bob
. Trong trường hợp này, nhãn @mike//pac/kage:target
có thể xử lý một mục tiêu bên trong michael
trong ngữ cảnh của alice
(lưu ý @
đơn).
Ngược lại, bạn có thể hiểu đây là một lớp ánh xạ kho lưu trữ: mỗi kho lưu trữ duy trì một lớp ánh xạ từ "tên kho lưu trữ hiển thị" đến "tên kho lưu trữ chuẩn".
Quy tắc kho lưu trữ
Một giản đồ cho các định nghĩa về kho lưu trữ cho Bazel biết cách cụ thể hoá một kho lưu trữ. Ví dụ: có thể là "tải tệp lưu trữ zip xuống từ một URL nhất định rồi giải nén tệp đó", hoặc "tìm nạp một cấu phần phần mềm Maven nhất định và cung cấp cấu phần phần mềm đó dưới dạng mục tiêu java_import
" hoặc đơn giản là "đường liên kết tượng trưng đến một thư mục cục bộ". Mỗi kho lưu trữ được xác định bằng cách gọi một quy tắc kho lưu trữ với số lượng đối số thích hợp.
Xem phần Quy tắc kho lưu trữ để biết thêm thông tin về cách viết các quy tắc kho lưu trữ của riêng bạn.
Cho đến nay, các quy tắc repo phổ biến nhất là http_archive
(tải tệp lưu trữ xuống từ một URL và trích xuất tệp đó), và local_repository
liên kết tượng trưng với một thư mục cục bộ đã là kho lưu trữ Bazel.
Tìm nạp kho lưu trữ
Thao tác cung cấp kho lưu trữ trên ổ đĩa cục bộ bằng cách chạy quy tắc kho lưu trữ liên kết. Các kho lưu trữ được xác định trong không gian làm việc sẽ không có trên ổ đĩa cục bộ trước khi được tìm nạp.
Thông thường, Bazel chỉ tìm nạp một kho lưu trữ khi cần một nội dung nào đó từ kho lưu trữ và kho lưu trữ đó chưa được tìm nạp. Nếu đã tìm nạp kho lưu trữ trước đó, thì Bazel chỉ tìm nạp lại nếu định nghĩa của kho lưu trữ đó thay đổi.
Bố cục thư mục
Sau khi được tìm nạp, bạn có thể tìm thấy kho lưu trữ này trong thư mục con external
trong
cơ sở đầu ra, theo tên chuẩn của kho lưu trữ.
Bạn có thể chạy lệnh sau để xem nội dung của kho lưu trữ với tên phiên bản chuẩn canonical_name
:
ls $(bazel info output_base)/external/ canonical_name
Quản lý các phần phụ thuộc bên ngoài bằng Bzlmod
Bzlmod, hệ thống con phần phụ thuộc bên ngoài mới, không hoạt động trực tiếp với các định nghĩa về repo. Thay vào đó, mô-đun này tạo một biểu đồ phần phụ thuộc từ các mô-đun, chạy phần mở rộng ở đầu biểu đồ và xác định các kho lưu trữ tương ứng.
Mô-đun Bazel là một dự án Bazel có thể có nhiều phiên bản, trong đó mỗi phiên bản phát hành siêu dữ liệu về các mô-đun khác mà nó phụ thuộc. Mô-đun phải có tệp MODULE.bazel
ở thư mục gốc của kho lưu trữ, bên cạnh tệp WORKSPACE
. Tệp này là tệp kê khai của mô-đun, khai báo tên, phiên bản, danh sách phần phụ thuộc và các thông tin khác. Sau đây là một ví dụ cơ bản:
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")
Mô-đun chỉ được liệt kê các phần phụ thuộc trực tiếp mà Bzlmod tra cứu trong một cơ sở đăng ký Bazel – theo mặc định là Cơ sở đăng ký trung tâm Bazel. Sổ đăng ký cung cấp các tệp MODULE.bazel
của các phần phụ thuộc, cho phép Bazel khám phá toàn bộ biểu đồ phần phụ thuộc bắc cầu trước khi thực hiện phân giải phiên bản.
Sau khi phân giải phiên bản, trong đó một phiên bản được chọn cho mỗi mô-đun, Bazel sẽ tham khảo lại sổ đăng ký để tìm hiểu cách xác định kho lưu trữ cho từng mô-đun (trong hầu hết các trường hợp, sử dụng http_archive
).
Mô-đun cũng có thể chỉ định các phần dữ liệu tuỳ chỉnh được gọi là thẻ. Các phần dữ liệu này được tiện ích mô-đun sử dụng sau khi phân giải mô-đun để xác định các kho lưu trữ bổ sung. Các tiện ích này có khả năng tương tự như quy tắc kho lưu trữ, cho phép chúng thực hiện các thao tác như I/O đối với tệp và gửi yêu cầu mạng. Ngoài ra, chúng cho phép Bazel tương tác với các hệ thống quản lý gói khác trong khi vẫn tôn trọng biểu đồ phần phụ thuộc được tạo từ các mô-đun Bazel.
Đường liên kết ngoài trên Bzlmod
- Ví dụ về cách sử dụng Bzlmod trong bazelbuild/ví dụ
- Cải tiến các phần phụ thuộc bên ngoài của Bazel (tài liệu thiết kế gốc của Bzlmod)
- Bài nói tại BazelCon 2021 về Bzlmod
- Buổi nói chuyện về Bzlmod trong Ngày cộng đồng Bazel
Xác định kho lưu trữ bằng WORKSPACE
Trước đây, bạn có thể quản lý các phần phụ thuộc bên ngoài bằng cách xác định kho lưu trữ trong tệp WORKSPACE
(hoặc WORKSPACE.bazel
). Tệp này có cú pháp tương tự như tệp BUILD
, sử dụng quy tắc repo thay vì quy tắc bản dựng.
Đoạn mã sau đây là ví dụ về cách sử dụng quy tắc kho lưu trữ http_archive
trong tệp WORKSPACE
:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "foo",
urls = ["https://example.com/foo.zip"],
sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)
Đoạn mã này xác định một kho lưu trữ có tên chính tắc là foo
. Theo mặc định, trong hệ thống WORKSPACE
, tên chuẩn hoá của một kho lưu trữ cũng là tên hiển thị của nó cho tất cả các kho lưu trữ khác.
Xem danh sách đầy đủ các hàm có trong tệp WORKSPACE
.
Những thiếu sót của hệ thống WORKSPACE
Trong những năm kể từ khi hệ thống WORKSPACE
ra mắt, người dùng đã báo cáo nhiều vấn đề, bao gồm:
- Bazel không đánh giá các tệp
WORKSPACE
của bất kỳ phần phụ thuộc nào, vì vậy, tất cả các phần phụ thuộc bắc cầu phải được xác định trong tệpWORKSPACE
của kho lưu trữ chính, ngoài các phần phụ thuộc trực tiếp. - Để giải quyết vấn đề này, các dự án đã sử dụng mẫu "deps.bzl", trong đó, các dự án xác định một macro xác định nhiều kho lưu trữ và yêu cầu người dùng gọi macro này trong tệp
WORKSPACE
.- Điều này cũng có vấn đề riêng: các macro không thể
load
các tệp.bzl
khác, vì vậy, các dự án này phải xác định các phần phụ thuộc bắc cầu trong macro "phần phụ thuộc" này hoặc giải quyết vấn đề này bằng cách yêu cầu người dùng gọi nhiều macro "phần phụ thuộc" theo lớp. - Bazel đánh giá tệp
WORKSPACE
theo tuần tự. Ngoài ra, các phần phụ thuộc được chỉ định bằnghttp_archive
với URL mà không có bất kỳ thông tin phiên bản nào. Điều này có nghĩa là không có cách nào đáng tin cậy để thực hiện việc phân giải phiên bản trong trường hợp các phần phụ thuộc kim cương (A
phụ thuộc vàoB
vàC
;B
vàC
đều phụ thuộc vào các phiên bản khác nhau củaD
).
- Điều này cũng có vấn đề riêng: các macro không thể
Do những thiếu sót của WORKSPACE, Bzlmod sẽ thay thế hệ thống WORKSPACE cũ trong các bản phát hành Bazel sau này. Vui lòng đọc hướng dẫn di chuyển Bzlmod để biết cách di chuyển sang Bzlmod.