Bazel xây dựng phần mềm từ mã nguồn được sắp xếp trong 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ệ thống phân cấp 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 dữ liệu nào
có thể được tạo ra từ nguồn.
Không gian làm việc
Không gian làm việc là cây thư mục trên hệ thống tệp của bạn, trong đó có chứa các tệp nguồn
cho phần 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 tên là 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 bắt buộc để tạo đầu ra.
Các thư mục chứa tệp có tên là WORKSPACE
được coi là gốc của
không gian làm việc. Do đó, Bazel bỏ qua mọi cây thư mục trong một không gian làm việc bị can thiệp vào
thư mục con có chứa tệp WORKSPACE
, vì các tệp 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, thì WORKSPACE.bazel
sẽ được sử 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 quy tắc không gian làm việc.
Các quy tắc không gian làm việc đi kèm với Bazel được ghi lại trong mục Quy tắc không gian làm việc trong Xây dựng bách khoa toàn thư và tài liệu về kho lưu trữ Starlark đã nhúng khác.
Vì kho lưu trữ bên ngoài cũng là kho lưu trữ, nên các kho lưu trữ đó cũng thường chứa tệp WORKSPACE
. Tuy nhiên, các tệp WORKSPACE
bổ sung này
bị Bazel bỏ qua. Cụ thể, các kho lưu trữ phụ thuộc vào nội dung tự động
không được thêm tự động.
Gói
Đơn vị chính của tổ chức mã trong kho lưu trữ là gói. Gói là một tập hợp các tệp liên quan và thông số kỹ thuật về cách sử dụng các tệp đó để tạo cấu phần phần mềm đầu ra.
Gói được định nghĩa là thư mục chứa một tệp có tên 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 và tất cả các thư mục con bên dưới một gói, ngoại trừ những thư mục con chứa tệp BUILD
. Từ định nghĩa này, không 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 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 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 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 là một trong hai loại chính, tệp và quy tắc.
Tệp được chia thành hai loại. Tệp nguồn thường được viết bởi nỗ lực của mọi người và được đăng ký vào kho lưu trữ. Tệp đã tạo, đôi khi được gọi là các tệp xuất ra hoặc tệp đầu ra, không được đăng ký mà được tạo từ các 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 đối tượng quy tắc chỉ định mối quan hệ giữa một tập hợp dữ liệu đầu vào và một tập hợp các tệp đầu ra. Dữ liệu nhập vào một quy tắc có thể là các tệp nguồn, nhưng cũng có thể là dữ liệu đầu ra của các quy tắc khác.
Cho dù giá trị nhập vào một quy tắc là tệp nguồn hay tệp được tạo ra trong hầu hết các trường hợp là quan trọng; điều quan trọng là nội dung của tệp đó. Thông tin 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ư trường hợp việc chịu trách nhiệm duy trì tệp có cấu trúc cao trở nên quá mệt mỏi và có người viết chương trình để lấy thông tin đó. Người tiêu dùng của tệp đó không cần phải thay đổi nữa. 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ỉ chứa các thay đổi địa phương.
Thông tin đầ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à tùy thuộc vào ngôn ngữ hoặc quy tắc, nhưng về trực quan, quy tắc này rất đơn giản: một quy tắc thư viện C++ có thể có một quy tắc thư viện C++ khác cho một mục nhập. Hiệu quả 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 ký hiệu 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 biến thể 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 thành một gói khác. Tuy nhiên, không có gì lạ khi các thông tin đầ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 có mục đích hạn chế khả năng truy cập của 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
.
Họ có 3 thuộc tính: danh sách các gói chứa, tên và các nhóm gói khác trong đó. Các cách duy nhất được phép tham chiếu đến các thuộc tính này là từ thuộc tính visibility
của các quy tắc hoặc từ thuộc tính default_visibility
của hàm package
; chứ không tạo hoặc tiêu thụ tệp.
Để biết thêm thông tin, hãy tham khảo
tài liệu về package_group
.