Bazel tạo phần mềm từ mã nguồn được sắp xếp trong một cây thư mục gọi 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 một 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 có 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.
Không gian làm việc
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 mà bạn muốn tạo. Mỗi không gian làm việc đều có một tệp văn bản có tên là WORKSPACE
. Tệp này có thể trống hoặc có thể chứa các tham chiếu đến các phần phụ thuộc bên ngoài cần thiết để tạo các đầ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 một 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 có gốc tại 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 một bí danh của tệp WORKSPACE
. Nếu cả hai tệp đều tồn tại, thì WORKSPACE.bazel
sẽ được dùng.
Kho lưu trữ
Mã được sắp xếp trong kho lưu trữ. Thư mục chứa tệp WORKSPACE
là thư mục gốc của kho lưu trữ chính, còn được gọi là @
. Các kho lưu trữ khác (bên ngoài) được xác định trong tệp WORKSPACE
bằng cách sử dụ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 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ì bản thân các kho lưu trữ bên ngoài cũng là kho lưu trữ, nên chúng thường chứa cả 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 một cách bắc cầu sẽ không được tự động thêm.
Gói
Đơn vị chính để tổ chức mã trong một kho lưu trữ là gói. Gói là một tập hợp các tệp liên quan và một quy cách về cách sử dụng các tệp đó để tạo ra các cấu phần phần mềm đầu ra.
Gói được xác định là một thư mục chứa tệp BUILD
có tên là BUILD
hoặc BUILD.bazel
. Một 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ả các thư mục con bên dưới, ngoại trừ những thư mục con có 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ể là một phần của hai gói khác nhau.
Ví dụ: trong cây thư mục sau đây có 2 gói là my/app
và gói con my/app/tests
. Xin lưu ý rằng my/app/data
không phải là một gói mà là một thư mục thuộc về 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à một vùng chứa gồm các 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 2 loại. Tệp nguồn thường được viết bởi nỗ lực của mọi người và được kiểm tra trong 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 phiên bản quy tắc chỉ định mối quan hệ giữa một nhóm tệp đầu vào và một nhóm tệp đầu ra. Đầu vào của 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.
Đầu vào của một quy tắc là tệp nguồn hay tệp được tạo trong hầu hết các trường hợp đều không quan trọng; điều quan trọng duy nhất là nội dung của tệp đó. Việc này giúp bạn dễ dàng thay thế một tệp nguồn phức tạp bằng một tệp được tạo theo quy tắc, chẳng hạn như khi việc duy trì thủ công một tệp có cấu trúc cao trở nên quá mệt mỏi và người dùng viết một chương trình để lấy tệp đó. Người dùng tệp đó không cần thay đổi gì. Ngược lại, một tệp được tạo có thể dễ dàng được thay thế bằng một tệp nguồn chỉ có các thay đổi cục bộ.
Đầu vào của 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ề mặt trực quan thì rất đơn giản: quy tắc A của thư viện C++ có thể có quy tắc B khác của thư viện C++ cho một đầu vào. Ảnh hưởng của phần phụ thuộc này là các tệp tiêu đề của B có sẵn cho A trong quá trình biên dịch, các biểu tượng của B có sẵn cho A trong quá trình liên kết và dữ liệu thời gian chạy của B có sẵn cho A trong quá trình thực thi.
Một bất biến 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. Tuy nhiên, không có gì lạ khi các đầu vào của một quy tắc đế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 hạn chế khả năng tiếp cận một số quy tắc nhất định. Các nhóm gói được xác định bằng hàm package_group
. Chúng có 3 thuộc tính: danh sách các gói mà chúng chứa, tên của chúng và các nhóm gói khác mà chúng bao gồm. Cách duy nhất được phép tham chiếu đến các tệp này là từ thuộc tính visibility
của quy tắc hoặc từ thuộc tính default_visibility
của hàm package
; các tệp 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
.