XÂY DỰNG các tệp

Các phần trước đã mô tả một cách trừu tượng về các gói, mục tiêu và nhãn, cũng như biểu đồ phần phụ thuộc của bản dựng. Phần này mô tả cú pháp cụ thể dùng để xác định một gói.

Theo định nghĩa, mọi gói đều chứa một tệp BUILD, đây là một chương trình ngắn.

Các tệp BUILD được đánh giá bằng một ngôn ngữ mệnh lệnh, Starlark.

Chúng được diễn giải dưới dạng danh sách tuần tự các câu lệnh.

Nói chung, thứ tự là quan trọng: ví dụ: các biến phải được xác định trước khi được sử dụng. Tuy nhiên, hầu hết các tệp BUILD chỉ bao gồm các khai báo về quy tắc bản dựng và thứ tự tương đối của các câu lệnh này là không quan trọng; điều quan trọng là những quy tắc nào đã được khai báo và với những giá trị nào, vào thời điểm quá trình đánh giá gói hoàn tất.

Khi một hàm quy tắc bản dựng, chẳng hạn như cc_library, được thực thi, hàm này sẽ tạo một mục tiêu mới trong biểu đồ. Mục tiêu này có thể được tham chiếu sau này bằng một nhãn.

Trong các tệp BUILD đơn giản, bạn có thể tự do sắp xếp lại các khai báo quy tắc mà không làm thay đổi hành vi.

Để khuyến khích việc tách biệt rõ ràng giữa mã và dữ liệu, các tệp BUILD không thể chứa định nghĩa hàm, câu lệnh for hoặc câu lệnh if (nhưng được phép dùng phép hiểu danh sách và biểu thức if). Thay vào đó, bạn có thể khai báo các hàm trong tệp .bzl. Ngoài ra, các đối số *args**kwargs không được phép dùng trong tệp BUILD; thay vào đó, hãy liệt kê rõ ràng tất cả các đối số.

Điều quan trọng là các chương trình trong Starlark không thể thực hiện thao tác I/O tuỳ ý. Bất biến này giúp việc diễn giải các tệp BUILD trở nên khép kín – chỉ phụ thuộc vào một tập hợp đầu vào đã biết, điều này rất cần thiết để đảm bảo rằng các bản dựng có thể tái tạo. Để biết thêm chi tiết, hãy xem phần Hermeticity.

Vì các tệp BUILD cần được cập nhật bất cứ khi nào các phần phụ thuộc của mã cơ bản thay đổi, nên thường có nhiều người trong một nhóm duy trì các tệp này. Tác giả tệp BUILD nên bình luận một cách tự do để ghi lại vai trò của từng mục tiêu bản dựng, cho dù mục tiêu đó có dành cho mục đích sử dụng công khai hay không, đồng thời ghi lại vai trò của chính gói đó.

Tải tiện ích

Tiện ích Bazel là các tệp có đuôi .bzl. Sử dụng câu lệnh load để nhập một ký hiệu từ một tiện ích.

load("//foo/bar:file.bzl", "some_library")

Đoạn mã này tải tệp foo/bar/file.bzl và thêm ký hiệu some_library vào môi trường. Bạn có thể dùng đoạn mã này để tải các quy tắc, hàm hoặc hằng số mới (ví dụ: một chuỗi hoặc một danh sách). Bạn có thể nhập nhiều ký hiệu bằng cách sử dụng các đối số bổ sung cho lệnh gọi đến load. Các đối số phải là chuỗi ký tự (không có biến) và câu lệnh load phải xuất hiện ở cấp cao nhất – chúng không thể nằm trong nội dung hàm.

Đối số đầu tiên của load là một nhãn xác định tệp .bzl. Nếu đó là một nhãn tương đối, thì nhãn đó sẽ được phân giải liên quan đến gói (không phải thư mục) chứa tệp bzl hiện tại. Nhãn tương đối trong câu lệnh load phải sử dụng dấu : ở đầu.

load cũng hỗ trợ bí danh, do đó, bạn có thể gán các tên khác nhau cho các ký hiệu đã nhập.

load("//foo/bar:file.bzl", library_alias = "some_library")

Bạn có thể xác định nhiều bí danh trong một câu lệnh load. Hơn nữa, danh sách đối số có thể chứa cả bí danh và tên ký hiệu thông thường. Ví dụ sau đây hoàn toàn hợp lệ (xin lưu ý thời điểm sử dụng dấu ngoặc kép).

load(":my_rules.bzl", "some_rule", nice_alias = "some_other_rule")

Trong tệp .bzl, các ký hiệu bắt đầu bằng _ sẽ không được xuất và không thể tải từ một tệp khác.

Bạn có thể sử dụng khả năng hiển thị tải để hạn chế những người có thể tải tệp .bzl.

Các loại quy tắc bản dựng

Phần lớn các quy tắc bản dựng đều thuộc về các họ, được nhóm lại theo ngôn ngữ. Ví dụ: cc_binary, cc_librarycc_test lần lượt là các quy tắc bản dựng cho tệp nhị phân, thư viện và kiểm thử C++. Các ngôn ngữ khác sử dụng cùng một sơ đồ đặt tên, với một tiền tố khác, chẳng hạn như java_* cho Java. Một số hàm trong số này được ghi lại trong Bách khoa toàn thư về bản dựng, nhưng bất kỳ ai cũng có thể tạo quy tắc mới.

  • Các quy tắc *_binary tạo chương trình thực thi bằng một ngôn ngữ nhất định. Sau khi bản dựng, tệp thực thi sẽ nằm trong cây đầu ra nhị phân của công cụ bản dựng tại tên tương ứng cho nhãn của quy tắc, vì vậy, //my:program sẽ xuất hiện tại (ví dụ) $(BINDIR)/my/program.

    Ở một số ngôn ngữ, các quy tắc như vậy cũng tạo một thư mục runfiles chứa tất cả các tệp được đề cập trong thuộc tính data thuộc về quy tắc hoặc bất kỳ quy tắc nào trong bao đóng bắc cầu của các phần phụ thuộc; tập hợp tệp này được thu thập cùng nhau ở một nơi để dễ dàng triển khai vào môi trường sản xuất.

  • Các quy tắc *_test là một chuyên môn hoá của quy tắc *_binary, dùng để kiểm thử tự động. Các bài kiểm thử chỉ đơn giản là các chương trình trả về 0 khi thành công.

    Giống như tệp nhị phân, các bài kiểm thử cũng có cây runfiles và các tệp bên dưới cây này là những tệp duy nhất mà một bài kiểm thử có thể mở một cách hợp lệ trong thời gian chạy. Ví dụ: một chương trình cc_test(name='x', data=['//foo:bar']) có thể mở và đọc $TEST_SRCDIR/workspace/foo/bar trong quá trình thực thi. (Mỗi ngôn ngữ lập trình có hàm hiệu dụng riêng để truy cập giá trị của $TEST_SRCDIR, nhưng tất cả đều tương đương với việc sử dụng trực tiếp biến môi trường.) Việc không tuân thủ quy tắc sẽ khiến bài kiểm thử không thành công khi được thực thi trên một máy chủ kiểm thử từ xa.

  • Các quy tắc *_library chỉ định các mô-đun được biên dịch riêng biệt bằng ngôn ngữ lập trình đã cho. Thư viện có thể phụ thuộc vào các thư viện khác, còn tệp nhị phân và bài kiểm thử có thể phụ thuộc vào thư viện, với hành vi biên dịch riêng biệt dự kiến.

Nhãn Phần phụ thuộc

Mã hoá tệp

Các tệp BUILD.bzl phải được mã hoá theo UTF-8, trong đó ASCII là một tập hợp con hợp lệ. Các chuỗi byte tuỳ ý hiện được cho phép, nhưng có thể ngừng được hỗ trợ trong tương lai.