Bazel có hỗ trợ tinh vi cho việc lập mô hình các nền tảng và chuỗi công cụ. Việc tích hợp hệ thống này với các dự án thực tế đòi hỏi sự hợp tác cẩn thận giữa chủ sở hữu mã, nhà duy trì quy tắc và nhà phát triển Bazel cốt lõi.
Trang này tóm tắt mục đích của các nền tảng và cho biết cách xây dựng bằng các nền tảng đó.
tl;dr: Các API nền tảng và chuỗi công cụ của Bazel hiện có sẵn nhưng sẽ không hoạt động
mọi nơi cho đến tất cả các quy tắc ngôn ngữ, select()
và các tệp tham chiếu cũ khác
đã được cập nhật. Công việc này đang diễn ra. Cuối cùng, tất cả các bản dựng đều sẽ dựa trên nền tảng.
Hãy đọc phần bên dưới để biết bản dựng của bạn phù hợp ở đâu.
Để xem tài liệu chính thức hơn, hãy xem:
Thông tin khái quát
Nền tảng và chuỗi công cụ được ra mắt để chuẩn hoá cách phần mềm các dự án nhắm đến các loại máy khác nhau và xây dựng bằng các công cụ ngôn ngữ phù hợp.
Đây là tính năng bổ sung tương đối mới cho Bazel. Có
truyền cảm hứng
qua quan sát thấy rằng các công ty duy trì ngôn ngữ đã làm việc này trong quảng cáo
theo cách tạm thời, không tương thích. Ví dụ: quy tắc C++ sử dụng --cpu
và --crosstool_top
để đặt CPU mục tiêu và chuỗi công cụ C++ của bản dựng. Không có mô hình nào trong số này chính xác
một "nền tảng". Những nỗ lực làm như vậy trước đây đã tạo ra các bản dựng khó sử dụng và không chính xác.
Những cờ này cũng không kiểm soát quá trình biên dịch Java, vốn tự phát triển
giao diện độc lập với --java_toolchain
.
Bazel dành cho các dự án lớn, đa ngôn ngữ và đa nền tảng. Chiến dịch này đòi hỏi hỗ trợ theo nguyên tắc hơn cho các khái niệm này, bao gồm các API rõ ràng khuyến khích khả năng tương tác giữa ngôn ngữ và dự án. Đây là những API mới này cho.
Di chuyển
Các API nền tảng và chuỗi công cụ chỉ hoạt động khi các dự án thực sự sử dụng chúng. Chiến dịch này
thì không hề đơn giản vì logic quy tắc, chuỗi công cụ, phần phụ thuộc và
select()
phải hỗ trợ chúng. Việc này đòi hỏi trình tự di chuyển cẩn thận
để tất cả dự án và phần phụ thuộc của chúng hoạt động chính xác.
Ví dụ: Nền tảng hỗ trợ Quy tắc C++. Nhưng Quy tắc của Apple thì không. Dự án C++ của bạn có thể không quan tâm đến Apple. Nhưng những người khác thì có thể. Loại đối thủ sau lượt đánh bóng việc bật các nền tảng cho mọi bản dựng C++ trên toàn cầu vẫn chưa an toàn.
Phần còn lại của trang này mô tả trình tự di chuyển này cũng như cách thức và thời điểm di chuyển dự án của bạn có thể phù hợp.
Mục tiêu
Quá trình di chuyển nền tảng của Bazel hoàn tất khi tất cả dự án được tạo bằng định dạng:
bazel build //:myproject --platforms=//:myplatform
Điều này có nghĩa là:
- Các quy tắc mà dự án của bạn sử dụng có thể suy ra chuỗi công cụ chính xác
//:myplatform
. - Các quy tắc mà phần phụ thuộc của dự án sử dụng có thể suy ra chuỗi công cụ chính xác
từ
//:myplatform
. - Hoặc dự án tuỳ thuộc vào mức độ hỗ trợ của bạn
//:myplatform
hoặc dự án của bạn dự án hỗ trợ các API cũ (như--crosstool_top
). //:myplatform
nội dung tham khảo [nội dung khai báo phổ biến][Nội dung khai báo chung về nền tảng]{: .external} vềCPU
,OS
và các khái niệm chung khác hỗ trợ tự động nhiều dự án khả năng tương thích.- Tất cả dự án có liên quan
select()
hiểu các thuộc tính máy được//:myplatform
ngụ ý. //:myplatform
được xác định tại một vị trí rõ ràng, có thể sử dụng lại: trong tệp kho lưu trữ nếu nền tảng đó là dành riêng cho dự án của bạn, nếu không thì ở một nơi nào đó cho tất cả các dự án có thể sử dụng nền tảng này có thể tìm thấy.
Các API cũ sẽ bị xoá ngay khi đạt được mục tiêu này. Sau đó, thao tác này sẽ là cách dự án tiêu chuẩn chọn nền tảng và chuỗi công cụ.
Tôi có nên sử dụng nền tảng không?
Nếu chỉ muốn tạo hoặc biên dịch chéo một dự án, bạn nên làm theo tài liệu chính thức của dự án.
Nếu là người duy trì dự án, ngôn ngữ hoặc chuỗi công cụ, chắc chắn bạn sẽ muốn để hỗ trợ các API mới. Bạn có đợi cho đến khi quá trình di chuyển chung hoàn tất hay không hoặc chọn sử dụng sớm tuỳ thuộc vào nhu cầu về giá trị / chi phí cụ thể của bạn:
Giá trị
- Bạn có thể
select()
hoặc chọn chuỗi công cụ trên đúng những tài sản mà bạn quan tâm thay vì cờ được cố định giá trị trong mã như--cpu
. Ví dụ: nhiều CPU có thể hỗ trợ cùng một tập lệnh. - Bản dựng chính xác hơn. Nếu bạn
select()
với--cpu
trong ví dụ trên, thì thêm một CPU mới hỗ trợ cùng một tập lệnh,select()
không nhận ra CPU mới. Tuy nhiên,select()
trên các nền tảng vẫn chính xác. - Trải nghiệm người dùng đơn giản hơn. Tất cả dự án đều hiểu rằng:
--platforms=//:myplatform
. Không cần nhiều ngôn ngữ cụ thể cờ trên dòng lệnh. - Thiết kế ngôn ngữ đơn giản hơn. Tất cả ngôn ngữ đều có chung một API để xác định chuỗi công cụ, sử dụng chuỗi công cụ và chọn chuỗi công cụ phù hợp cho nền tảng.
- Bạn có thể bỏ qua các mục tiêu trong giai đoạn xây dựng và kiểm thử nếu chúng không tương thích với nền tảng mục tiêu.
Chi phí
- Các dự án phụ thuộc chưa hỗ trợ nền tảng có thể không tự động hoạt động với sản phẩm của bạn.
- Để chúng hoạt động, bạn có thể cần phải bảo trì tạm thời thêm.
- Để các API mới và cũ có thể cùng tồn tại, người dùng cần phải hướng dẫn người dùng kỹ càng hơn để để tránh nhầm lẫn.
- Định nghĩa chuẩn cho các thuộc tính phổ biến như
OS
vàCPU
vẫn đang trong quá trình phát triển và có thể cần thêm khoản đóng góp ban đầu. - Các định nghĩa chuẩn cho chuỗi công cụ theo ngôn ngữ cụ thể vẫn đang phát triển và có thể cần đóng góp thêm ban đầu.
Đánh giá API
platform
là một tập hợp
constraint_value
mục tiêu:
platform(
name = "myplatform",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:arm",
],
)
constraint_value
là một máy
thuộc tính này. Giá trị thuộc cùng một loại được nhóm theo một chỉ số chung
constraint_setting
:
constraint_setting(name = "os")
constraint_value(
name = "linux",
constraint_setting = ":os",
)
constraint_value(
name = "mac",
constraint_setting = ":os",
)
toolchain
là một quy tắc Starlark.
khai báo công cụ của ngôn ngữ (như compiler =
"//mytoolchain:custom_gcc"
). Thẻ providers (nhà cung cấp)
thông tin này cho các quy tắc cần xây dựng bằng các công cụ này.
Chuỗi công cụ khai báo constraint_value
máy mà chúng có thể
mục tiêu
(target_compatible_with = ["@platforms//os:linux"]
) và máy móc mà công cụ của họ có thể
chạy trên
(exec_compatible_with = ["@platforms//os:mac"]
).
Khi xây dựng $ bazel build //:myproject --platforms=//:myplatform
, Bazel
tự động chọn một chuỗi công cụ có thể chạy trên máy xây dựng và
tạo tệp nhị phân cho //:myplatform
. Đây gọi là quá trình giải quyết bằng chuỗi công cụ.
Bạn có thể đăng ký tập hợp các chuỗi công cụ có sẵn trong WORKSPACE
bằng
register_toolchains
hoặc tại
dòng lệnh bằng --extra_toolchains
.
Xem tại đây để biết thông tin chi tiết hơn.
Trạng thái
Khả năng hỗ trợ nền tảng hiện tại sẽ khác nhau giữa các ngôn ngữ. Mọi quy tắc chính của Bazel đều chuyển sang các nền tảng. Tuy nhiên, quá trình này sẽ mất nhiều thời gian. Điều này là do ba lý do chính:
Bạn phải cập nhật logic của quy tắc để nhận thông tin về công cụ từ chuỗi công cụ mới" API (
ctx.toolchains
) và ngừng đọc các chế độ cài đặt cũ như--cpu
và--crosstool_top
. Việc này tương đối đơn giản.Nhà duy trì chuỗi công cụ phải xác định chuỗi công cụ và giúp người dùng dễ dàng truy cập vào chuỗi công cụ người dùng (trong kho lưu trữ GitHub và các mục nhập
WORKSPACE
). Việc này đơn giản về mặt kỹ thuật nhưng phải được sắp xếp một cách thông minh để duy trì trải nghiệm người dùng dễ dàng.Bạn cũng cần định nghĩa nền tảng (trừ phi bạn tạo bản dựng cho cùng một máy Bazel tiếp tục chạy). Nhìn chung, các dự án nên xác định nền tảng riêng.
Bạn phải di chuyển các dự án hiện có.
select()
và chuyển đổi cũng phải đã di chuyển. Đây là thách thức lớn nhất. Đặc biệt khó khăn đối với dự án đa ngôn ngữ (có thể không thành công nếu tất cả các ngôn ngữ đều không đọc được--platforms
).
Nếu đang thiết kế một bộ quy tắc mới, bạn phải hỗ trợ các nền tảng từ đầu tiên. Điều này tự động làm cho các quy tắc của bạn tương thích với các quy tắc và dự án, với giá trị ngày càng tăng khi API nền tảng trở nên phổ biến hơn.
Các thuộc tính phổ biến của nền tảng
Các thuộc tính nền tảng như OS
và CPU
phổ biến trong các dự án nên
được khai báo ở một nơi tiêu chuẩn và tập trung. Điều này khuyến khích việc thực hiện giữa nhiều dự án
và khả năng tương thích với nhiều ngôn ngữ.
Ví dụ: nếu MyApp có một select()
trên constraint_value
@myapp//cpus:arm
và SomeCommonLib có select()
trên
@commonlib//constraints:arm
, những ứng dụng này sẽ kích hoạt "cánh tay" của chúng có chế độ không tương thích
tiêu chí.
Các thuộc tính phổ biến trên toàn cầu được khai báo trong
Kho lưu trữ @platforms
(vì vậy, nhãn chuẩn cho ví dụ trên là @platforms//cpu:arm
).
Các thuộc tính phổ biến về ngôn ngữ phải được khai báo trong kho lưu trữ của các thuộc tính tương ứng
ngôn ngữ.
Nền tảng mặc định
Nói chung, chủ dự án nên xác định
platforms để mô tả
loại máy mà họ muốn xây dựng. Sau đó, các báo cáo này được kích hoạt bằng
--platforms
.
Khi bạn không thiết lập --platforms
, Bazel sẽ mặc định dùng platform
đại diện cho
cục bộ. Nội dung này được tạo tự động tại @local_config_platform//:host
nên bạn không cần phải xác định rõ ràng. Chế độ này ánh xạ OS
của máy cục bộ
và CPU
với constraint_value
được khai báo trong
@platforms
.
C++
Các quy tắc C++ của Bazel sử dụng nền tảng để chọn chuỗi công cụ khi bạn thiết lập
--incompatible_enable_cc_toolchain_resolution
(#7260).
Điều này có nghĩa là bạn có thể định cấu hình dự án C++ bằng:
bazel build //:my_cpp_project --platforms=//:myplatform
thay vì phiên bản cũ:
bazel build //:my_cpp_project` --cpu=... --crosstool_top=... --compiler=...
Nếu dự án của bạn là C++ thuần tuý và không bị phụ thuộc bởi các dự án không phải C++, bạn có thể sử dụng
miễn là select
và
chuyển đổi là tương thích. Xem
#7260 và
Định cấu hình chuỗi công cụ C++ để được hướng dẫn thêm.
Chế độ này không được bật theo mặc định. Điều này là do các dự án của Apple
vẫn định cấu hình các phần phụ thuộc C++ bằng --cpu
và --crosstool_top
(ví dụ). Vì vậy, điều này phụ thuộc vào các quy tắc của Apple khi di chuyển sang nền tảng.
Java
Các quy tắc Java của Bazel sử dụng các nền tảng.
Thao tác này sẽ thay thế các cờ cũ --java_toolchain
, --host_java_toolchain
,
--javabase
và --host_javabase
.
Để tìm hiểu cách sử dụng cờ cấu hình, hãy xem hướng dẫn sử dụng Bazel và Java. Để biết thêm thông tin, hãy xem Tài liệu thiết kế.
Nếu bạn vẫn đang sử dụng cờ cũ, hãy làm theo quy trình di chuyển trong Vấn đề #7849.
Android
Các quy tắc Android của Bazel sử dụng các nền tảng để chọn chuỗi công cụ khi bạn thiết lập
--incompatible_enable_android_toolchain_resolution
.
Tính năng này không được bật theo mặc định. Tuy nhiên, quá trình di chuyển đang diễn ra thuận lợi.
Quả táo
Các quy tắc Apple của Bazel chưa hỗ trợ các nền tảng chọn chuỗi công cụ Apple.
Các lớp này cũng không hỗ trợ các phần phụ thuộc C++ có hỗ trợ nền tảng vì các phần phụ thuộc này sử dụng
--crosstool_top
cũ để đặt chuỗi công cụ C++. Cho đến khi chế độ này được di chuyển, bạn
có thể kết hợp các dự án Apple với C++ có hỗ trợ platorm với nền tảng
ánh xạ
(ví dụ).
Ngôn ngữ khác
- Hỗ trợ đầy đủ cho các quy tắc Rust của Bazel nền tảng.
- Hỗ trợ đầy đủ các quy tắc Go của Bazel nền tảng (thông tin chi tiết).
Nếu bạn đang thiết kế quy tắc cho một ngôn ngữ mới, hãy sử dụng nền tảng để chọn chuỗi công cụ của ngôn ngữ của bạn. Xem tài liệu về chuỗi công cụ để tham khảo hướng dẫn từng bước.
select()
Những dự án có thể select()
trên
constraint_value
mục tiêu nhưng chưa hoàn thành
nền tảng. Điều này là được thiết kế để select()
hỗ trợ nhiều loại
máy tính nhiều nhất có thể. Một thư viện có các nguồn cụ thể là ARM
sẽ hỗ trợ
tất cả máy hỗ trợ ARM
trừ khi có lý do cụ thể hơn.
Để chọn một hoặc nhiều constraint_value
, hãy sử dụng:
config_setting(
name = "is_arm",
constraint_values = [
"@platforms//cpu:arm",
],
)
Điều này tương đương với việc chọn theo cách truyền thống trên --cpu
:
config_setting(
name = "is_arm",
values = {
"cpu": "arm",
},
)
Bạn có thể xem thêm thông tin tại đây.
select
trên --cpu
, --crosstool_top
, v.v. không hiểu --platforms
. Thời gian
di chuyển dự án của bạn sang nền tảng, bạn phải chuyển đổi họ thành
constraint_values
hoặc dùng mối liên kết nền tảng để hỗ trợ
cả hai kiểu thông qua cửa sổ di chuyển.
Kiểu chuyển cảnh
Thay đổi về hiệu ứng chuyển đổi Starlark
gắn cờ các phần của biểu đồ bản dựng. Nếu dự án của bạn sử dụng hiệu ứng chuyển đổi
đặt --cpu
, --crossstool_top
hoặc cờ cũ, các quy tắc đọc
--platforms
sẽ không thấy những thay đổi này.
Khi di chuyển dự án sang nền tảng, bạn phải chuyển đổi các thay đổi như
return { "//command_line_option:cpu": "arm" }
đến return {
"//command_line_option:platforms": "//:my_arm_platform" }
hoặc sử dụng nền tảng
ánh xạ để hỗ trợ cả hai kiểu trong quá trình di chuyển
cửa sổ.
Cách sử dụng các nền tảng hiện nay
Nếu chỉ muốn tạo hoặc biên dịch chéo một dự án, bạn nên làm theo tài liệu chính thức của dự án. Điều này phụ thuộc vào ngôn ngữ và những người duy trì dự án xác định cách thức và thời điểm tích hợp với các nền tảng cũng như lợi ích mà nền tảng đó mang lại.
Nếu bạn là một chương trình duy trì dự án, ngôn ngữ hoặc chuỗi công cụ nhưng bản dựng của bạn lại không sử dụng nền tảng theo mặc định, bạn có ba lựa chọn (ngoài việc chờ người dùng di chuyển):
Bật chế độ "Sử dụng nền tảng" gắn cờ cho các ngôn ngữ của dự án (nếu các ngôn ngữ đó có một) và thực hiện bất kỳ thử nghiệm nào cần thiết để xem liệu dự án bạn có quan tâm hay không về công việc.
Nếu các dự án bạn quan tâm vẫn phụ thuộc vào cờ cũ như
--cpu
và--crosstool_top
, sử dụng các mã này cùng với--platforms
:bazel build //:my_mixed_project --platforms==//:myplatform --cpu=... --crosstool_top=...
Việc này tốn một ít chi phí bảo trì (bạn phải đảm bảo chế độ cài đặt theo cách thủ công ). Nhưng điều này sẽ hiệu quả trong trường hợp không có hành vi nổi loạn chuyển đổi.
Viết ánh xạ nền tảng để hỗ trợ cả hai kiểu bằng cách ánh xạ các chế độ cài đặt kiểu
--cpu
đến các nền tảng tương ứng và ngược lại.
Liên kết nền tảng
Ánh xạ nền tảng là một API tạm thời cho phép logic dựa trên phiên bản cũ cùng tồn tại trong cùng một bản dựng khi các phiên bản cũ ngừng hoạt động cửa sổ.
Ánh xạ nền tảng là bản đồ của platform()
đến một
bộ cờ cũ tương ứng hoặc đảo ngược. Ví dụ:
platforms:
# Maps "--platforms=//platforms:ios" to "--cpu=ios_x86_64 --apple_platform_type=ios".
//platforms:ios
--cpu=ios_x86_64
--apple_platform_type=ios
flags:
# Maps "--cpu=ios_x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
--cpu=ios_x86_64
--apple_platform_type=ios
//platforms:ios
# Maps "--cpu=darwin --apple_platform_type=macos" to "//platform:macos".
--cpu=darwin
--apple_platform_type=macos
//platforms:macos
Bazel sử dụng mã này để đảm bảo tất cả các chế độ cài đặt, cả dựa trên nền tảng và cũ, được áp dụng nhất quán trong suốt quá trình xây dựng, bao gồm cả thông qua chuyển đổi.
Theo mặc định, Bazel sẽ đọc các tệp ánh xạ từ tệp platform_mappings
trong
không gian làm việc gốc. Bạn cũng có thể đặt
--platform_mappings=//:my_custom_mapping
.
Xem tại đây để biết toàn bộ thông tin chi tiết.
Câu hỏi
Nếu bạn có câu hỏi và dịch vụ hỗ trợ chung về tiến trình di chuyển, hãy liên hệ bazel-discuss@googlegroups.com hoặc chủ sở hữu của các quy tắc phù hợp.
Để thảo luận về việc thiết kế và phát triển các API nền tảng/chuỗi công cụ, thông tin liên hệ bazel-dev@googlegroups.com.