Bazel tạo phần mềm từ mã nguồn được sắp xếp trong một cây thư mục có tên là không gian làm việc. Các tệp nguồn trong không gian làm việc được sắp xếp theo hệ phân cấp lồng nhau của các gói, trong đó mỗi gói là một thư mục chứa một tập hợp các tệp nguồn liên quan và một tệp BUILD
. Tệp BUILD
chỉ định những đầu ra phần mềm có thể được tạo từ nguồn.
Workspace
Không gian làm việc là một cây thư mục trên hệ thống tệp của bạn, chứa các tệp nguồn cho phần mềm bạn muốn xây dựng. Mỗi không gian làm việc có một tệp văn bản có tên WORKSPACE
. Tệp này có thể trống hoặc có thể chứa các tệp tham chiếu đến các phần phụ thuộc bên ngoài cần thiết để tạo đầu ra.
Các thư mục chứa tệp có tên là WORKSPACE
được coi là thư mục gốc của
không gian làm việc. Do đó, Bazel sẽ bỏ qua mọi cây thư mục trong một không gian làm việc bắt nguồn từ một thư mục con chứa tệp WORKSPACE
, vì các cây thư mục này tạo thành một không gian làm việc khác.
Bazel cũng hỗ trợ tệp WORKSPACE.bazel
dưới dạng bí danh của tệp WORKSPACE
. Nếu cả hai tệp đều tồn tại, WORKSPACE.bazel
sẽ được sử dụng.
Kho lưu trữ
Mã được sắp xếp trong repositories. Thư mục chứa tệp WORKSPACE
là gốc của kho lưu trữ chính, còn gọi là @
. Các kho lưu trữ (bên ngoài) khác được xác định trong tệp WORKSPACE
bằng các quy tắc không gian làm việc hoặc được tạo từ các mô-đun và tiện ích trong hệ thống Bzlmod. Hãy xem bài viết tổng quan về các phần phụ thuộc bên ngoài để biết thêm thông tin.
Các quy tắc không gian làm việc đi kèm với Bazel được ghi lại trong phần Quy tắc không gian làm việc trong Bách khoa toàn thư về bản dựng và tài liệu về các quy tắc kho lưu trữ Starlark được nhúng.
Vì kho lưu trữ bên ngoài là chính kho lưu trữ, nên các kho lưu trữ này cũng thường chứa tệp WORKSPACE
. Tuy nhiên, Bazel sẽ bỏ qua các tệp WORKSPACE
bổ sung này. Cụ thể, các kho lưu trữ phụ thuộc vào bắc cầu không được thêm tự động.
Gói
Đơn vị chính để sắp xếp mã trong kho lưu trữ là gói. Gói là một tập hợp các tệp có liên quan và thông số kỹ thuật về cách dùng các tệp đó để tạo ra cấu phần phần mềm đầu ra.
Gói được xác định là một thư mục chứa một tệp có tên là BUILD
(hoặc BUILD.bazel
). Gói bao gồm tất cả các tệp trong thư mục của gói, cộng với tất cả thư mục con bên dưới, ngoại trừ những thư mục con chứa tệp BUILD
.
Theo định nghĩa này, không có tệp hoặc thư mục nào có thể thuộc hai gói khác nhau.
Ví dụ: trong cây thư mục sau đây, có hai gói là my/app
và gói con my/app/tests
. Xin lưu ý my/app/data
không phải là một gói mà là một thư mục thuộc gói my/app
.
src/my/app/BUILD
src/my/app/app.cc
src/my/app/data/input.txt
src/my/app/tests/BUILD
src/my/app/tests/test.cc
Mục tiêu
Gói là vùng chứa mục tiêu được xác định trong tệp BUILD
của gói. Hầu hết các mục tiêu đều thuộc một trong hai loại chính là tệp và quy tắc.
Các tệp được chia thành hai loại. Tệp nguồn thường được viết bằng nỗ lực của mọi người và được đăng ký vào kho lưu trữ. Tệp được tạo (đôi khi được gọi là tệp phái sinh hoặc tệp đầu ra) không được kiểm tra, nhưng được tạo từ tệp nguồn.
Loại mục tiêu thứ hai được khai báo bằng một quy tắc. Mỗi thực thể quy tắc chỉ định mối quan hệ giữa một tập hợp các tệp đầu vào và một tập hợp các tệp đầu ra. Dữ liệu đầu vào cho một quy tắc có thể là tệp nguồn, nhưng cũng có thể là đầu ra của các quy tắc khác.
Trong hầu hết các trường hợp, việc đầu vào của một quy tắc là tệp nguồn hay tệp được tạo đều không quan trọng; điều quan trọng chỉ là nội dung của tệp đó. Điều này giúp bạn dễ dàng thay thế tệp nguồn phức tạp bằng tệp được tạo bằng một quy tắc, chẳng hạn như khi gánh nặng duy trì tệp có cấu trúc phức tạp theo cách thủ công trở nên quá mệt mỏi và ai đó viết một chương trình để lấy tệp đó. Người dùng của tệp đó không bắt buộc phải thay đổi. Ngược lại, tệp đã tạo có thể dễ dàng được thay thế bằng tệp nguồn chỉ có những thay đổi cục bộ.
Dữ liệu đầu vào cho một quy tắc cũng có thể bao gồm các quy tắc khác. Ý nghĩa chính xác của các mối quan hệ như vậy thường khá phức tạp và phụ thuộc vào ngôn ngữ hoặc quy tắc, nhưng về trực quan, ý nghĩa này rất đơn giản: quy tắc thư viện C++ A có thể có một quy tắc thư viện C++ B khác cho dữ liệu đầu vào. Tác động của phần phụ thuộc này là các tệp tiêu đề của B sẽ được cung cấp cho A trong quá trình biên dịch, các biểu tượng của B sẽ được cung cấp cho A trong quá trình liên kết và dữ liệu thời gian chạy của B sẽ được cung cấp cho A trong quá trình thực thi.
Một hằng số của tất cả các quy tắc là các tệp do một quy tắc tạo ra luôn thuộc cùng một gói với chính quy tắc đó; không thể tạo tệp vào một gói khác. Mặc dù vậy, nhiều trường hợp dữ liệu đầu vào của một quy tắc lại đến từ một gói khác.
Nhóm gói là tập hợp các gói nhằm mục đích giới hạn khả năng truy cập của một số quy tắc nhất định. Nhóm gói được xác định bằng hàm package_group
. Các đối tượng này có 3 thuộc tính: danh sách các gói chứa trong đó, tên và các nhóm gói khác có trong đó. Bạn chỉ được phép sử dụng thuộc tính visibility
của các quy tắc hoặc thuộc tính default_visibility
của hàm package
để tham chiếu đến các quy tắc này. Các cách này không tạo hoặc sử dụng tệp. Để biết thêm thông tin, hãy tham khảo tài liệu về package_group
.