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 của bạn mà không phải từ không gian làm việc của bạn. Ví dụ: chúng có thể là bộ quy tắc được lưu trữ trong kho lưu trữ GitHub, cấu phần phần mềm Maven hoặc một thư mục trên máy 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ó hai cách để quản lý các phần phụ thuộc bên ngoài với Bazel:
hệ thống WORKSPACE
truyền thống tập trung vào kho lưu trữ, và
hệ thống MODULE.bazel
mới tập trung vào mô-đun (có tên mã là Bzlmod,
và được bật bằng cờ --enable_bzlmod
). Bạn có thể sử dụng cả hai hệ thống này
với nhau, nhưng Bzlmod sẽ thay thế hệ thống WORKSPACE
trong Bazel trong tương lai
bản phát hành mới, hãy xem hướng dẫn di chuyển về Bzlmod để biết cách
di chuyển.
Tài liệu này giải thích các khái niệm về quản lý phần phụ thuộc bên ngoài ở Bazel, trước khi đi sâu hơn một chút về thứ tự của hai hệ thống này.
Khái niệm
Kho lưu trữ
Cây thư mục có một tệp đánh dấu ranh giới ở gốc chứa nguồn có thể sử dụng trong bản dựng Bazel. Thường được rút ngắn thành kho lưu trữ.
Tệp đánh dấu ranh giới của kho lưu trữ có thể là MODULE.bazel
(báo hiệu rằng kho lưu trữ này
đại diện cho mô-đun Bazel), REPO.bazel
(xem bên dưới) hoặc trong
ngữ cảnh cũ, WORKSPACE
hoặc WORKSPACE.bazel
. Tệp đánh dấu ranh giới kho lưu trữ bất kỳ
sẽ biểu thị ranh giới của một kho lưu trữ; nhiều tệp như vậy có thể cùng tồn tại trong một
thư mục.
Kho lưu trữ chính
Kho lưu trữ nơi lệnh Bazel hiện tại đang được chạy.
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 về "kho lưu trữ" và "workspace" là trộn lẫn; từ khoá "không gian làm việc" thường được dùng để chỉ kho lưu trữ 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 hoá
Tên chuẩn hoá của kho lưu trữ có thể định địa chỉ. Trong bối cảnh
nhưng mỗi kho lưu trữ đều có một tên chuẩn duy nhất. Một mục tiêu bên trong một kho lưu trữ
nhãn có thể ghi địa chỉ của tên chuẩn là canonical_name
@@canonical_name//pac/kage:target
(xin lưu ý @
gấp đôi).
Kho lưu trữ chính luôn sử dụng chuỗi trống làm tên chuẩn.
Tên kho lưu trữ biểu kiến
Tên của một kho lưu trữ có thể xác định được trong ngữ cảnh của một kho lưu trữ nhất định khác.
Đây có thể được coi là "biệt hiệu" của kho lưu trữ: Kho lưu trữ có tên chuẩn
michael
có thể có tên rõ ràng là mike
theo bối cảnh của kho lưu trữ
alice
, nhưng có thể có tên rõ ràng là mickey
trong bối cảnh của kho lưu trữ
bob
. Trong trường hợp này, nhãn có thể định địa chỉ một mục tiêu bên trong michael
@mike//pac/kage:target
trong ngữ cảnh alice
(lưu ý @
duy nhất).
Ngược lại, đây có thể được hiểu là một mối liên kết kho lưu trữ: mỗi kho lưu trữ duy trì bản đồ từ "tên kho lưu trữ rõ ràng" thành "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 kho lưu trữ cho Bazel biết cách cụ thể hoá một
kho lưu trữ. Ví dụ: trạng thái 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 nó" 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ột
java_import
đích" hoặc đơn giản là "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 ghi 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 rồi trích xuất URL đó, và
local_repository
liên kết với
thư mục cục bộ đã là kho lưu trữ Bazel.
Tìm nạp kho lưu trữ
Hành động tạo một kho lưu trữ có sẵn trên ổ đĩa cục bộ bằng cách chạy kho lưu trữ quy tắc repo. Các kho lưu trữ được xác định trong một không gian làm việc không có sẵn trên ổ đĩa cục bộ trước khi chúng được tìm nạp.
Thông thường, Bazel chỉ tìm nạp một kho lưu trữ khi cần thứ gì đó từ kho lưu trữ đó, và kho lưu trữ này chưa được tìm nạp. Nếu kho lưu trữ đã được tìm nạp trước đó, Bazel chỉ tìm nạp lại nếu định nghĩa của lớp này thay đổi.
Bạn có thể dùng lệnh fetch
để bắt đầu tìm nạp trước kho lưu trữ,
nhắm mục tiêu hoặc tất cả các kho lưu trữ cần thiết để thực hiện bất kỳ bản dựng nào. Chức năng này
bật bản dựng ngoại tuyến bằng cách sử dụng tuỳ chọn --nofetch
.
Tuỳ chọn --fetch
dùng để quản lý quyền truy cập mạng. Giá trị mặc định của giá trị này là true.
Tuy nhiên, khi bạn đặt thành false (--nofetch
), lệnh này sẽ sử dụng mọi
phiên bản của phần phụ thuộc và nếu không có phiên bản nào, lệnh này sẽ dẫn đến
lỗi.
Xem tuỳ chọn tìm nạp để biết thêm thông tin thông tin về kiểm soát tìm nạp.
Bố cục thư mục
Sau khi 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, dưới tên chuẩn.
Bạn có thể chạy lệnh sau để xem nội dung của kho lưu trữ bằng
tên chuẩn canonical_name
:
ls $(bazel info output_base)/external/ canonical_name
Tệp REPO.bazel
Tệp REPO.bazel
dùng để đánh dấu ranh giới trên cùng của cây thư mục
tạo thành một kho lưu trữ. Không cần chứa bất kỳ nội dung nào để làm kho lưu trữ
tệp ranh giới; tuy nhiên, bạn cũng có thể sử dụng thuộc tính này để chỉ định một số thuộc tính phổ biến
cho tất cả các mục tiêu bản dựng bên trong kho lưu trữ.
Cú pháp của tệp REPO.bazel
tương tự như tệp BUILD
, ngoại trừ việc không có
Các câu lệnh load
được hỗ trợ và chỉ có một hàm duy nhất là repo()
sẵn có. repo()
nhận cùng đối số với package()
hàm trong các tệp BUILD
; trong khi package()
chỉ định thuộc tính chung cho mọi mục tiêu bản dựng bên trong gói, repo()
tương tự như vậy cho tất cả mục tiêu bản dựng bên trong kho lưu trữ.
Ví dụ: bạn có thể chỉ định một giấy phép chung cho tất cả các mục tiêu trong kho lưu trữ của mình bằng cách
có tệp REPO.bazel
sau:
repo(
default_package_metadata = ["//:my_license"],
)
Quản lý các phần phụ thuộc bên ngoài bằng Bzlmod
Bzlmod, hệ thống con mới cho phần phụ thuộc bên ngoài, không trực tiếp hoạt động với kho lưu trữ định nghĩa. Thay vào đó, phương thức 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 kho lưu trữ sao cho phù hợp.
Một Bazel Mô-đun là một dự án Bazel có thể chứa nhiều
các phiên bản, mỗi phiên bản trong số đó xuất bản siêu dữ liệu về các mô-đun khác mà nó phụ thuộc
. Một mô-đun phải có tệp MODULE.bazel
ở gốc kho lưu trữ, bên cạnh
WORKSPACE
. Tệp này là tệp kê khai của mô-đun, khai báo tên của mô-đun,
phiên bản, danh sách phần phụ thuộc và nhiều thông tin khác. Sau đây là một số nguyên tắc cơ bản
ví dụ:
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ột 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
Danh mục Bazel — theo mặc định, Bazel Central
Sổ đăng ký. Sổ đăng ký cung cấp
phần phụ thuộc MODULE.bazel
tệp để cho phép Bazel khám phá toàn bộ
biểu đồ phần phụ thuộc bắc cầu trước khi 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 tham khảo ý kiến của tổ chức quản lý tên miền một lần nữa để tìm hiểu cách xác định kho lưu trữ cho mỗi mô-đun
(trong hầu hết các trường hợp, sử dụng http_archive
).
Các mô-đun cũng có thể chỉ định các phần dữ liệu tuỳ chỉnh được gọi là thẻ, được tiện ích mô-đun tiêu thụ 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ó các tính năng tương tự như kho lưu trữ quy tắc, cho phép chúng thực hiện các hành động như I/O tệp và mạng gửi yêu cầu. Ngoài ra, chúng cho phép Bazel tương tác với gói khác hệ thống quản lý đồng thời vẫn tôn trọng biểu đồ phần phụ thuộc xây dựng từ Bazel các mô-đun.
Đường liên kết ngoài trên Bzlmod
- Ví dụ về cách sử dụng Bzlmod trong bazelbuild/ví dụ
- Sửa chữa 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)
- Buổi trò chuyện về BazelCon 2021 về Bzlmod
- Buổi nói chuyện trên 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 các kho lưu trữ trong
Tệp WORKSPACE
(hoặc WORKSPACE.bazel
). Tệp này có cú pháp tương tự như
BUILD
, sử dụng quy tắc kho lưu trữ thay vì quy tắc bản dựng.
Đoạn mã sau đây là một 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ã xác định một repo có tên chuẩn là foo
. Trong WORKSPACE
system, theo mặc định, tên chuẩn của một kho lưu trữ cũng chính là tên rõ ràng của nó để
tất cả các kho lưu trữ khác.
Xem danh sách đầy đủ các hàm có trong
WORKSPACE
tệp.
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á 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ữ, bên cạnh 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 "deps.bzl" mẫu, trong đó
chúng xác định một macro, sau đó xác định nhiều kho lưu trữ và yêu cầu người dùng
hãy gọi macro này trong tệp
WORKSPACE
.- Tệp này có những vấn đề riêng: 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 của chúng trong "dep" hoặc giải quyết vấn đề này bằng cách để người dùng gọi nhiều lần các "deps" theo lớp macro. - Bazel đánh giá tệp
WORKSPACE
theo tuần tự. Ngoài ra, phần phụ thuộc được chỉ định bằnghttp_archive
với URL mà không có bất kỳ phần phụ thuộc nào thông tin phiên bản. Điều này có nghĩa là không có cách nào đáng tin cậy để thực hiện độ phân giải phiên bản trong trường hợp 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
).
- Tệp này có những vấn đề riêng: macro không thể
Do những thiếu sót của WORKSPACE, nên Bzlmod sẽ thay thế phiên bản cũ Hệ thống WORKSPACE trong các bản phát hành sau này của Bazel. Vui lòng đọc phần di chuyển Bzlmod về cách di chuyển sang Bzlmod.