Quy tắc chung

Quy tắc

bí danh

alias(name, actual, compatible_with, deprecation, features, restricted_to, tags, target_compatible_with, testonly, visibility)

Quy tắc alias tạo một tên khác mà bạn có thể dùng để gọi quy tắc đó.

Hiện tượng chồng phổ chỉ hoạt động cho các mục tiêu "thông thường". Cụ thể, package_grouptest_suite không được đặt bí danh.

Quy tắc bí danh có phần khai báo riêng về chế độ hiển thị. Ở tất cả các khía cạnh khác, nó hoạt động giống như quy tắc mà quy tắc đó tham chiếu (ví dụ: chỉ kiểm thử trên bí danh sẽ bị bỏ qua; thay vào đó, tính năng chỉ kiểm thử của quy tắc được tham chiếu) với một số ngoại lệ nhỏ:

  • Kiểm thử sẽ không chạy nếu bí danh của kiểm thử được đề cập trên dòng lệnh. Để xác định một bí danh chạy kiểm thử được tham chiếu, hãy sử dụng quy tắc test_suite với một mục tiêu duy nhất trong thuộc tính tests.
  • Khi xác định nhóm môi trường, bí danh cho các quy tắc environment không được hỗ trợ. Các hàm này cũng không được hỗ trợ trong tuỳ chọn dòng lệnh --target_environment.

Ví dụ

filegroup(
    name = "data",
    srcs = ["data.txt"],
)

alias(
    name = "other",
    actual = ":data",
)

Đối số

Thuộc tính
name

Name; required

Tên duy nhất cho mục tiêu này.

actual

Label; required

Mục tiêu mà bí danh này đề cập. Dữ liệu này không nhất thiết phải là quy tắc mà cũng có thể là một tệp đầu vào.

config_setting

config_setting(name, constraint_values, define_values, deprecation, distribs, features, flag_values, licenses, tags, testonly, values, visibility)

Khớp với trạng thái cấu hình dự kiến (được biểu thị dưới dạng cờ bản dựng hoặc các điều kiện ràng buộc của nền tảng) nhằm mục đích kích hoạt các thuộc tính có thể định cấu hình. Hãy xem phần chọn để biết cách sử dụng quy tắc này và Các thuộc tính có thể định cấu hình để biết thông tin tổng quan về tính năng chung.

Ví dụ

Các bản dựng sau đây phù hợp với mọi bản dựng đặt --compilation_mode=opt hoặc -c opt (có thể xuất hiện rõ ràng ở dòng lệnh hoặc ngầm ẩn từ các tệp .bazelrc):

  config_setting(
      name = "simple",
      values = {"compilation_mode": "opt"}
  )
  

Các bản dựng sau đây khớp với mọi bản dựng nhắm đến ARM và áp dụng FOO=bar định nghĩa tuỳ chỉnh (ví dụ: bazel build --cpu=arm --define FOO=bar ...):

  config_setting(
      name = "two_conditions",
      values = {
          "cpu": "arm",
          "define": "FOO=bar"
      }
  )
  

Các bản dựng sau đây phù hợp với mọi bản dựng đặt cờ do người dùng xác định --//custom_flags:foo=1 (một cách rõ ràng tại dòng lệnh hoặc ngầm định từ các tệp .bazelrc):

  config_setting(
      name = "my_custom_flag_is_set",
      flag_values = { "//custom_flags:foo": "1" },
  )
  

Các bản dựng sau đây phù hợp với mọi bản dựng nhắm đến một nền tảng có cấu trúc x86_64 và glibc phiên bản 2.25, giả sử có constraint_value có nhãn //example:glibc_2_25. Xin lưu ý rằng một nền tảng vẫn khớp nếu xác định thêm các giá trị ràng buộc khác ngoài 2 giá trị này.

  config_setting(
      name = "64bit_glibc_2_25",
      constraint_values = [
          "@platforms//cpu:x86_64",
          "//example:glibc_2_25",
      ]
  )
  
Trong mọi trường hợp như vậy, cấu hình có thể thay đổi trong bản dựng, chẳng hạn như khi cần tạo mục tiêu cho một nền tảng khác với nền tảng phụ thuộc. Tức là ngay cả khi config_setting không khớp với cờ dòng lệnh cấp cao nhất, nó vẫn có thể khớp với một số mục tiêu bản dựng.

Ghi chú

  • Xem phần chọn để biết điều gì sẽ xảy ra khi nhiều config_setting khớp với trạng thái cấu hình hiện tại.
  • Đối với cờ hỗ trợ dạng viết tắt (ví dụ: --compilation_mode-c), các khai báo định nghĩa values phải sử dụng dạng đầy đủ. Các lệnh gọi này sẽ tự động so khớp các lệnh gọi này bằng một trong hai biểu mẫu.
  • Nếu một cờ nhận nhiều giá trị (chẳng hạn như --copt=-Da --copt=-Db hoặc cờ Starlark thuộc danh sách), thì values = { "flag": "a" } sẽ khớp nếu "a" hiện diện ở bất cứ đâu trong danh sách thực tế.

    values = { "myflag": "a,b" } hoạt động theo cách tương tự: tuỳ chọn này khớp với --myflag=a --myflag=b, --myflag=a --myflag=b --myflag=c, --myflag=a,b--myflag=c,b,a. Có sự khác biệt về ngữ nghĩa chính xác giữa các cờ. Ví dụ: --copt không hỗ trợ nhiều giá trị trong cùng một phiên bản: --copt=a,b tạo ra ["a,b"] trong khi --copt=a --copt=b tạo ra ["a", "b"] (vì vậy values = { "copt": "a,b" } khớp với giá trị cũ nhưng không khớp với giá trị trước). Nhưng --ios_multi_cpus (đối với các quy tắc của Apple) : -ios_multi_cpus=a,bios_multi_cpus=a --ios_multi_cpus=b đều tạo ra ["a", "b"]. Kiểm tra các định nghĩa về cờ và kiểm tra kỹ các điều kiện của bạn để xác minh đúng kỳ vọng.

  • Nếu bạn cần xác định những điều kiện không được lập mô hình bằng cờ bản dựng tích hợp sẵn, hãy sử dụng cờ do Starlark xác định. Bạn cũng có thể dùng --define nhưng chế độ hỗ trợ yếu hơn và không được khuyên dùng. Hãy xem tại đây để thảo luận thêm.
  • Tránh lặp lại các định nghĩa config_setting giống nhau trong các gói khác nhau. Thay vào đó, hãy tham chiếu một config_setting phổ biến được xác định trong một gói chuẩn.
  • Bạn có thể sử dụng values, define_valuesconstraint_values theo cách kết hợp bất kỳ trong cùng một config_setting nhưng phải đặt ít nhất một thuộc tính cho config_setting nhất định.

Đối số

Thuộc tính
name

Name; required

Tên duy nhất cho mục tiêu này.

constraint_values

List of labels; optional; nonconfigurable

Tập hợp constraint_values tối thiểu mà nền tảng mục tiêu phải chỉ định để khớp với config_setting này. (Ở đây chúng tôi không xem xét đến nền tảng thực thi.) Mọi giá trị ràng buộc bổ sung mà nền tảng đã bỏ qua sẽ bị bỏ qua. Hãy xem phần Thuộc tính bản dựng có thể định cấu hình để biết thông tin chi tiết.

Trong trường hợp hai config_setting đều khớp trong cùng một select, thuộc tính này sẽ không được xem xét để xác định xem một trong hai config_setting có phải là đặc điểm của thuộc tính còn lại hay không. Nói cách khác, một config_setting không thể khớp với một nền tảng mạnh hơn một nền tảng khác.

define_values

Dictionary: String -> String; optional; nonconfigurable

Giống như values nhưng dành riêng cho cờ --define.

--define đặc biệt vì cú pháp (--define KEY=VAL) có nghĩa KEY=VAL là một giá trị xét từ góc nhìn cờ Bazel.

Tức là:

            config_setting(
                name = "a_and_b",
                values = {
                    "define": "a=1",
                    "define": "b=2",
                })
          

không hoạt động vì cùng một khoá (define) xuất hiện hai lần trong từ điển. Thuộc tính này sẽ giải quyết vấn đề đó:

            config_setting(
                name = "a_and_b",
                define_values = {
                    "a": "1",
                    "b": "2",
                })
          

khớp chính xác với bazel build //foo --define a=1 --define b=2.

--define vẫn có thể xuất hiện trong values với cú pháp cờ thông thường và có thể tuỳ ý kết hợp với thuộc tính này, miễn là các khoá từ điển vẫn khác biệt.

flag_values

Dictionary: label -> String; optional; nonconfigurable

Giống như values nhưng dành cho cờ bản dựng do người dùng xác định.

Đây là một thuộc tính riêng biệt vì cờ do người dùng xác định được tham chiếu dưới dạng nhãn, còn cờ tích hợp được tham chiếu dưới dạng chuỗi tuỳ ý.

values

Dictionary: String -> String; optional; nonconfigurable

Tập hợp giá trị cấu hình phù hợp với quy tắc này (được biểu thị dưới dạng cờ bản dựng)

Quy tắc này kế thừa cấu hình của mục tiêu đã định cấu hình tham chiếu đến mục tiêu đó trong câu lệnh select. Lệnh gọi này được coi là "khớp" với lệnh gọi Bazel nếu, với mọi mục nhập trong từ điển, cấu hình của lệnh gọi này khớp với giá trị dự kiến của mục nhập. Ví dụ: values = {"compilation_mode": "opt"} khớp với các lệnh gọi bazel build --compilation_mode=opt ...bazel build -c opt ... trên các quy tắc được định cấu hình mục tiêu.

Để thuận tiện, các giá trị cấu hình sẽ được chỉ định là cờ bản dựng (không có "--" trước đó). Tuy nhiên, hãy lưu ý rằng hai giá trị này không giống nhau. Điều này là do các mục tiêu có thể được xây dựng trong nhiều cấu hình trong cùng một bản dựng. Ví dụ: "cpu" của cấu hình máy chủ lưu trữ khớp với giá trị của --host_cpu chứ không phải --cpu. Vì vậy, nhiều thực thể của cùng một config_setting có thể khớp với cùng một lệnh gọi theo cách khác nhau, tuỳ thuộc vào cấu hình của quy tắc sử dụng các thực thể đó.

Nếu một cờ không được đặt rõ ràng ở dòng lệnh, thì giá trị mặc định của cờ đó sẽ được sử dụng. Nếu một khóa xuất hiện nhiều lần trong từ điển, thì chỉ trường hợp cuối cùng được sử dụng. Nếu một khoá tham chiếu đến một cờ có thể được đặt nhiều lần trên dòng lệnh (ví dụ: bazel build --copt=foo --copt=bar --copt=baz ...), thì quá trình so khớp sẽ xảy ra nếu bất kỳ chế độ cài đặt nào trong số đó trùng khớp.

nhóm tệp

filegroup(name, srcs, data, compatible_with, deprecation, distribs, features, licenses, output_group, restricted_to, tags, target_compatible_with, testonly, visibility)

Hãy sử dụng filegroup để đặt tên thuận tiện cho một tập hợp mục tiêu. Sau đó, bạn có thể tham chiếu những quy tắc này từ các quy tắc khác.

Bạn nên sử dụng filegroup thay vì tham chiếu trực tiếp các thư mục. Tệp thứ hai không có âm thanh vì hệ thống xây dựng không có toàn bộ kiến thức về mọi tệp bên dưới thư mục. Vì vậy, hệ thống có thể không tạo lại được khi các tệp này thay đổi. Khi được kết hợp với glob, filegroup có thể đảm bảo rằng hệ thống xây dựng đã biết rõ tất cả các tệp.

Ví dụ

Để tạo một filegroup bao gồm 2 tệp nguồn, hãy thực hiện

filegroup(
    name = "mygroup",
    srcs = [
        "a_file.txt",
        "some/subdirectory/another_file.txt",
    ],
)

Hoặc sử dụng glob để tạo thư mục testdata:

filegroup(
    name = "exported_testdata",
    srcs = glob([
        "testdata/*.dat",
        "testdata/logs/**/*.log",
    ]),
)

Để sử dụng các định nghĩa này, hãy tham chiếu filegroup với nhãn từ quy tắc bất kỳ:

cc_library(
    name = "my_library",
    srcs = ["foo.cc"],
    data = [
        "//my_package:exported_testdata",
        "//my_package:mygroup",
    ],
)

Đối số

Thuộc tính
name

Name; required

Tên duy nhất cho mục tiêu này.

srcs

List of labels; optional

Danh sách các mục tiêu là thành viên của nhóm tệp.

Thông thường, người dùng sẽ sử dụng kết quả của một biểu thức glob cho giá trị của thuộc tính srcs.

data

List of labels; optional

Danh sách các tệp cần thiết cho quy tắc này trong thời gian chạy.

Các mục tiêu có tên trong thuộc tính data sẽ được thêm vào runfiles của quy tắc filegroup này. Khi filegroup được tham chiếu trong thuộc tính data của một quy tắc khác, runfiles của nó sẽ được thêm vào runfiles của quy tắc phụ thuộc. Hãy xem phần các phần phụ thuộc dữ liệutài liệu chung về data để biết thêm thông tin về cách phụ thuộc và sử dụng tệp dữ liệu.

output_group

String; optional

Nhóm đầu ra để thu thập cấu phần phần mềm từ các nguồn. Nếu bạn chỉ định thuộc tính này, các cấu phần phần mềm từ nhóm đầu ra được chỉ định của các phần phụ thuộc sẽ được xuất thay vì nhóm đầu ra mặc định.

"Nhóm đầu ra" là một danh mục cấu phần phần mềm đầu ra của một mục tiêu, được chỉ định trong quá trình triển khai quy tắc đó.

truy vấn tạo

genquery(name, deps, data, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, expression, features, licenses, opts, restricted_to, scope, strict, tags, target_compatible_with, testonly, visibility)

genquery() chạy truy vấn được chỉ định bằng Ngôn ngữ truy vấn làm sáng và kết xuất kết quả vào một tệp.

Để đảm bảo bản dựng nhất quán, truy vấn chỉ được phép truy cập vào trạng thái đóng bắc cầu của các mục tiêu đã chỉ định trong thuộc tính scope. Các truy vấn vi phạm quy tắc này sẽ không thành công trong quá trình thực thi nếu strict không được chỉ định hoặc đúng (nếu strict là sai, các mục tiêu ngoài phạm vi sẽ bị bỏ qua kèm theo cảnh báo). Cách dễ nhất để đảm bảo điều này không xảy ra là đề cập đến cùng các nhãn trong phạm vi như trong biểu thức truy vấn.

Điểm khác biệt duy nhất giữa các truy vấn được phép ở đây và trên dòng lệnh là các truy vấn có chứa thông số kỹ thuật mục tiêu theo ký tự đại diện (ví dụ: //pkg:* hoặc //pkg:all) không được cho phép ở đây. Có 2 lý do dẫn đến điều này: một là vì genquery phải chỉ định một phạm vi để ngăn các mục tiêu nằm ngoài trạng thái đóng bắc cầu của truy vấn nhằm ảnh hưởng đến kết quả của truy vấn; và thứ hai, vì tệp BUILD không hỗ trợ các phần phụ thuộc ký tự đại diện (ví dụ: không được phép deps=["//a/..."]).

Kết quả của truy vấn tạo được sắp xếp bằng --order_output=full để thực thi đầu ra tất định.

Tên của tệp đầu ra là tên của quy tắc.

Ví dụ

Ví dụ này ghi danh sách các nhãn trong phương thức đóng bắc cầu của mục tiêu được chỉ định vào một tệp.

genquery(
    name = "kiwi-deps",
    expression = "deps(//kiwi:kiwi_lib)",
    scope = ["//kiwi:kiwi_lib"],
)

Đối số

Thuộc tính
name

Name; required

Tên duy nhất cho mục tiêu này.

expression

String; required

Truy vấn sẽ được thực thi. Trái ngược với dòng lệnh và các vị trí khác trong tệp BUILD, các nhãn ở đây được phân giải tương ứng với thư mục gốc của không gian làm việc. Ví dụ: nhãn :b trong thuộc tính này trong tệp a/BUILD sẽ tham chiếu đến mục tiêu //:b.
opts

List of strings; optional

Các tuỳ chọn được chuyển đến công cụ truy vấn. Các đối tượng này tương ứng với các tuỳ chọn dòng lệnh có thể được chuyển đến bazel query. Không được phép sử dụng một số tùy chọn truy vấn tại đây: --keep_going, --query_file, --universe_scope, --order_results--order_output. Các tuỳ chọn không được chỉ định ở đây sẽ có giá trị mặc định giống như trên dòng lệnh bazel query.
scope

null; required

Phạm vi của truy vấn. Truy vấn không được phép chạm vào các mục tiêu bên ngoài trạng thái đóng bắc cầu của các mục tiêu này.
strict

Boolean; optional; default is True

Nếu giá trị là true, các mục tiêu có truy vấn thoát khỏi trạng thái đóng bắc cầu của phạm vi sẽ không tạo được. Nếu giá trị là false, Bazel sẽ in một cảnh báo và bỏ qua bất kỳ đường dẫn truy vấn nào đã đưa nó ra ngoài phạm vi, trong khi hoàn tất phần còn lại của truy vấn.

quy tắc gen

genrule(name, srcs, outs, cmd, cmd_bash, cmd_bat, cmd_ps, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, exec_tools, executable, features, licenses, local, message, output_licenses, output_to_bindir, restricted_to, tags, target_compatible_with, testonly, toolchains, tools, visibility)

genrule tạo một hoặc nhiều tệp bằng lệnh Bash do người dùng xác định.

Quy tắc tạo sinh là các quy tắc bản dựng chung mà bạn có thể sử dụng nếu không có quy tắc cụ thể nào cho tác vụ. Ví dụ: bạn có thể chạy một lớp lót Bash. Tuy nhiên, nếu bạn cần biên dịch tệp C++, hãy tuân theo các quy tắc cc_* hiện có, vì mọi phần việc nặng nhọc đã được thực hiện cho bạn.

Không sử dụng quy tắc tạo sinh để chạy kiểm thử. Có các quy trình phân phối đặc biệt cho kiểm thử và kết quả kiểm thử, bao gồm cả chính sách lưu vào bộ nhớ đệm và các biến môi trường. Thường thì quá trình kiểm thử cần được chạy sau khi bản dựng hoàn tất và trên cấu trúc mục tiêu, trong khi các quy tắc tạo sinh được thực thi trong quá trình tạo bản dựng và trên kiến trúc máy chủ lưu trữ (hai quy tắc này có thể khác nhau). Nếu bạn cần một quy tắc kiểm thử mục đích chung, hãy sử dụng sh_test.

Các cân nhắc về việc biên dịch chéo

Xem hướng dẫn sử dụng để biết thêm thông tin về tính năng biên dịch chéo.

Mặc dù quy tắc gen chạy trong một bản dựng, nhưng kết quả của quy tắc này thường được dùng sau quá trình tạo bản dựng, để triển khai hoặc kiểm thử. Hãy xem xét ví dụ biên dịch mã C cho bộ vi điều khiển: trình biên dịch chấp nhận các tệp nguồn C và tạo mã chạy trên bộ vi điều khiển. Mã được tạo rõ ràng là không thể chạy trên CPU được dùng để xây dựng mã, nhưng chính trình biên dịch C (nếu được biên dịch từ nguồn) thì phải chạy như vậy.

Hệ thống xây dựng sử dụng cấu hình máy chủ lưu trữ để mô tả(các) máy mà bản dựng chạy trên đó và cấu hình mục tiêu để mô tả(các) máy mà đầu ra của bản dựng sẽ chạy trên đó. Tệp này cung cấp các tuỳ chọn để định cấu hình từng tệp trong số này và phân tách các tệp tương ứng vào các thư mục riêng biệt để tránh xung đột.

Đối với quy tắc tạo, hệ thống xây dựng đảm bảo rằng các phần phụ thuộc được xây dựng phù hợp: srcs được tạo (nếu cần) cho cấu hình mục tiêu, tools được tạo cho cấu hình máy chủ và dữ liệu đầu ra được coi là dành cho cấu hình mục tiêu. Tệp này cũng cung cấp các biến "Tạo" mà các lệnh quy tắc tạo sinh có thể truyền đến các công cụ tương ứng.

Có ý định rằng quy tắc gen không xác định thuộc tính deps: các quy tắc tích hợp khác dùng thông tin meta phụ thuộc vào ngôn ngữ được truyền giữa các quy tắc để tự động xác định cách xử lý các quy tắc phụ thuộc. Tuy nhiên, mức độ tự động hoá này không thể thực hiện được đối với quy tắc gen. Quy tắc tạo sinh chỉ hoạt động ở cấp tệp và tệp runfile.

Trường hợp đặc biệt

Biên dịch máy chủ-máy chủ: trong một số trường hợp, hệ thống xây dựng cần chạy quy tắc tạo sinh để có thể thực thi kết quả trong quá trình xây dựng. Chẳng hạn, nếu một quy tắc tạo dựng tạo một số trình biên dịch tuỳ chỉnh mà sau đó được một quy tắc tạo sinh khác sử dụng, thì quy tắc đầu tiên phải tạo đầu ra cho cấu hình máy chủ lưu trữ, vì đó là nơi trình biên dịch sẽ chạy trong quy tắc gen khác. Trong trường hợp này, hệ thống xây dựng sẽ tự động làm điều đúng đắn: hệ thống tạo srcsouts của quy tắc tạo sinh đầu tiên cho cấu hình máy chủ lưu trữ thay vì cấu hình mục tiêu. Vui lòng xem hướng dẫn sử dụng để biết thêm thông tin.

Công cụ JDK và C++: để sử dụng một công cụ trong JDK hoặc bộ biên dịch C++, hệ thống xây dựng sẽ cung cấp một tập hợp các biến để sử dụng. Xem phần Biến"Tạo" để biết thông tin chi tiết.

Môi trường quy tắc tạo sinh

Lệnh gen thống được thực thi bằng một shell Bash được định cấu hình sẽ không thành công khi một lệnh hoặc quy trình không thành công, bằng cách sử dụng set -e -o pipefail.

Công cụ xây dựng thực thi lệnh Bash trong môi trường quy trình được dọn dẹp, chỉ xác định các biến cốt lõi như PATH, PWD, TMPDIR và một số biến khác. Để đảm bảo rằng các bản dựng có thể tái tạo, hầu hết các biến được xác định trong môi trường shell của người dùng không được truyền qua lệnh của quy tắc gen. Tuy nhiên, Bazel (chứ không phải Blaze) sẽ truyền qua giá trị của biến môi trường PATH của người dùng. Mọi thay đổi đối với giá trị của PATH sẽ khiến Bazel thực thi lại lệnh trong bản dựng tiếp theo.

Lệnh gen thống không được truy cập vào mạng ngoại trừ việc kết nối các quy trình là phần tử con của chính lệnh đó, mặc dù lệnh này hiện không được thực thi.

Hệ thống xây dựng tự động xoá mọi tệp đầu ra hiện có, nhưng sẽ tạo mọi thư mục mẹ cần thiết trước khi chạy quy tắc tạo sinh. Thao tác này cũng sẽ xoá mọi tệp đầu ra trong trường hợp không thực hiện được.

Lời khuyên chung

  • Hãy đảm bảo rằng các công cụ chạy theo quy tắc mang tính quyết định và ẩn giấu. Các đối tượng này không nên ghi dấu thời gian vào đầu ra và nên sử dụng thứ tự ổn định cho các tập hợp và bản đồ, cũng như chỉ ghi các đường dẫn tệp tương đối đến đầu ra, không phải đường dẫn tuyệt đối. Việc không tuân theo quy tắc này sẽ dẫn đến hành vi không mong muốn của bản dựng (Bazel không tạo lại quy tắc gen mà bạn nghĩ là sẽ làm) và làm giảm hiệu suất của bộ nhớ đệm.
  • Sử dụng $(location) rộng rãi cho kết quả đầu ra, công cụ và nguồn. Do việc phân tách các tệp đầu ra cho những cấu hình khác nhau, quy tắc tạo sinh không thể dựa vào các đường dẫn tuyệt đối và/hoặc được cố định giá trị trong mã.
  • Hãy viết một macro Starlark phổ biến trong trường hợp các quy tắc tạo giống nhau hoặc rất giống nhau được sử dụng ở nhiều vị trí. Nếu quy tắc tạo sinh phức tạp, hãy cân nhắc triển khai quy tắc đó trong một tập lệnh hoặc dưới dạng quy tắc Starlark. Điều này giúp cải thiện khả năng đọc cũng như khả năng kiểm thử.
  • Đảm bảo rằng mã thoát chỉ ra chính xác trạng thái thành công hay thất bại của quy tắc tạo sinh.
  • Đừng viết thông báo cho stdout hoặc stderr. Mặc dù hữu ích cho việc gỡ lỗi, nhưng quy tắc này có thể dễ dàng trở thành nhiễu; một quy tắc tạo thành công phải là im lặng. Mặt khác, quy tắc gen không thành công sẽ phát đi thông báo lỗi hợp lệ.
  • $$ evaluates to a $, a literal dollar-sign, so in order to invoke a shell command containing dollar-signs such as ls $(dirname $x), one must escape it thus: ls $$(dirname $$x).
  • Tránh tạo liên kết tượng trưng và thư mục. Bazel không sao chép cấu trúc thư mục/đường liên kết tượng trưng được tạo bằng quy tắc tạo ra và việc kiểm tra phần phụ thuộc của các thư mục không hợp lý.
  • Khi tham chiếu quy tắc tạo sinh trong các quy tắc khác, bạn có thể sử dụng nhãn của quy tắc tạo sinh hoặc nhãn của từng tệp đầu ra. Đôi khi phương pháp này dễ đọc hơn, đôi khi phương pháp còn lại: tham chiếu kết quả đầu ra theo tên trong srcs của quy tắc sử dụng sẽ tránh vô tình nhận các kết quả khác của quy tắc gen, nhưng có thể trở nên tẻ nhạt nếu quy tắc gen tạo ra nhiều đầu ra.

Ví dụ

Ví dụ này tạo foo.h. Không có nguồn nào vì lệnh này không nhận bất kỳ dữ liệu đầu vào nào. "Tệp nhị phân" do lệnh chạy là tập lệnh perl trong cùng một gói với quy tắc gen.

genrule(
    name = "foo",
    srcs = [],
    outs = ["foo.h"],
    cmd = "./$(location create_foo.pl) > \"$@\"",
    tools = ["create_foo.pl"],
)

Ví dụ sau đây cho thấy cách sử dụng filegroup và kết quả của một genrule khác. Xin lưu ý rằng việc sử dụng $(SRCS) thay vì lệnh $(location) tường minh cũng sẽ mang lại hiệu quả. Ví dụ này sử dụng lệnh sau chỉ để minh hoạ.

genrule(
    name = "concat_all_files",
    srcs = [
        "//some:files",  # a filegroup with multiple files in it ==> $(locations)
        "//other:gen",   # a genrule with a single output ==> $(location)
    ],
    outs = ["concatenated.txt"],
    cmd = "cat $(locations //some:files) $(location //other:gen) > $@",
)

Đối số

Thuộc tính
name

Name; required

Tên duy nhất cho mục tiêu này.


Bạn có thể tham chiếu đến quy tắc này theo tên trong mục srcs hoặc deps của các quy tắc BUILD khác. Nếu quy tắc này tạo tệp nguồn, thì bạn nên sử dụng thuộc tính srcs.
srcs

List of labels; optional

Danh sách dữ liệu đầu vào cho quy tắc này, chẳng hạn như tệp nguồn cần xử lý.

Thuộc tính này không phù hợp để liệt kê các công cụ do cmd thực thi. Thay vào đó, hãy sử dụng thuộc tính tools cho các công cụ đó.

Hệ thống xây dựng đảm bảo xây dựng các điều kiện tiên quyết này trước khi chạy lệnh gen thống. Các điều kiện tiên quyết này được xây dựng bằng cấu hình giống như yêu cầu bản dựng ban đầu. Tên của các tệp của những điều kiện tiên quyết này có sẵn cho lệnh dưới dạng một danh sách được phân tách bằng dấu cách trong $(SRCS); ngoài ra, bạn có thể lấy đường dẫn của một mục tiêu srcs riêng lẻ //x:y bằng cách sử dụng $(location //x:y) hoặc sử dụng $< miễn là đó là mục duy nhất trong srcs.

outs

List of filenames; required; nonconfigurable

Danh sách các tệp được tạo theo quy tắc này.

Tệp đầu ra không được vượt quá ranh giới của gói. Tên tệp đầu ra được diễn giải là có liên quan đến gói.

Nếu bạn đặt cờ executable, thì outs phải chứa đúng một nhãn.

Lệnh gen thống dự kiến sẽ tạo mỗi tệp đầu ra tại một vị trí đã xác định trước. Vị trí này có trong cmd bằng cách sử dụng biến "Make" dành riêng cho quy tắc tạo sinh ($@, $(OUTS), $(@D) hoặc $(RULEDIR)) hoặc bằng cách thay thế $(location).

cmd

String; optional

Lệnh cần chạy. Có thể thay thế $(location) biến"Tạo".
  1. Thao tác thay thế $(location) đầu tiên sẽ được áp dụng, thay thế tất cả các lần xuất hiện của $(location label)$(locations label) (và các cấu trúc tương tự sử dụng các biến execpath, execpaths, rootpathrootpaths liên quan).
  2. Tiếp theo, biến"Tạo" được mở rộng. Xin lưu ý rằng các biến được xác định trước $(JAVA), $(JAVAC)$(JAVABASE) mở rộng trong cấu hình máy chủ lưu trữ. Vì vậy, các lệnh gọi Java chạy trong một bước của bản dựng có thể tải chính xác thư viện chia sẻ và các phần phụ thuộc khác.
  3. Cuối cùng, lệnh thu được sẽ được thực thi bằng shell Bash. Nếu mã thoát khác 0 thì lệnh sẽ được coi là không thành công.
Đây là phương án dự phòng của cmd_bash, cmd_pscmd_bat, nếu không có phương án nào trong số đó phù hợp.

Nếu độ dài dòng lệnh vượt quá giới hạn của nền tảng (64K trên Linux/macOS, 8K trên Windows), thì quy tắc gen sẽ ghi lệnh vào một tập lệnh và thực thi tập lệnh đó để giải quyết vấn đề. Cách này áp dụng cho tất cả các thuộc tính cmd (cmd, cmd_bash, cmd_ps, cmd_bat).

cmd_bash

String; optional

Chạy lệnh Bash.

Thuộc tính này có mức độ ưu tiên cao hơn cmd. Lệnh được mở rộng và chạy theo cách tương tự như thuộc tính cmd.

cmd_bat

String; optional

Lệnh Batch để chạy trên Windows.

Thuộc tính này có mức độ ưu tiên cao hơn cmdcmd_bash. Lệnh này chạy theo cách tương tự như thuộc tính cmd nhưng có những điểm khác biệt sau:

  • Thuộc tính này chỉ áp dụng trên Windows.
  • Lệnh này chạy bằng cmd.exe /c với các đối số mặc định sau:
    • /S – bỏ dấu ngoặc kép đầu và cuối rồi thực thi mọi dấu ngoặc kép khác.
    • /E:ON – bật bộ lệnh mở rộng.
    • /V:ON – bật tính năng mở rộng biến bị trễ
    • /D – bỏ qua các mục nhập đăng ký AutoRun.
  • Sau khi thay thế $(location)biến"Make", các đường dẫn sẽ được mở rộng thành đường dẫn kiểu Windows (có dấu gạch chéo ngược).
cmd_ps

String; optional

Lệnh Powershell để chạy trên Windows.

Thuộc tính này có mức độ ưu tiên cao hơn cmd, cmd_bashcmd_bat. Lệnh này chạy theo cách tương tự như thuộc tính cmd, nhưng có những điểm khác biệt sau:

  • Thuộc tính này chỉ áp dụng trên Windows.
  • Lệnh này chạy bằng powershell.exe /c.

Để giúp Powershell dễ sử dụng hơn và ít xảy ra lỗi hơn, chúng ta chạy các lệnh sau để thiết lập môi trường trước khi thực thi lệnh Powershell trong quy tắc gen.

  • Set-ExecutionPolicy -Scope CurrentUser RemoteSigned – cho phép chạy các tập lệnh chưa ký.
  • $errorActionPreference='Stop' – Trong trường hợp có nhiều lệnh được phân tách bằng ;, thao tác sẽ thoát ngay lập tức nếu Powershell CmdLet không thành công, nhưng thao tác này KHÔNG hoạt động đối với lệnh bên ngoài.
  • $PSDefaultParameterValues['*:Encoding'] = 'utf8' – thay đổi phương thức mã hoá mặc định từ utf-16 thành utf-8.
exec_tools

List of labels; optional

Danh sách các phần phụ thuộc của công cụ đối với quy tắc này. Thuộc tính này hoạt động giống hệt như thuộc tính tools, ngoại trừ việc các phần phụ thuộc này sẽ được định cấu hình cho nền tảng thực thi của quy tắc thay vì cấu hình máy chủ lưu trữ. Điều này có nghĩa là các phần phụ thuộc trong exec_tools không phải tuân theo các giới hạn giống như các phần phụ thuộc trong tools. Cụ thể, chúng không bắt buộc phải sử dụng cấu hình máy chủ cho các phần phụ thuộc bắc cầu của riêng chúng. Hãy xem tools để biết thêm thông tin chi tiết.

Nhóm Blaze đang di chuyển tất cả cách sử dụng tools để dùng ngữ nghĩa exec_tools. Người dùng nên ưu tiên dùng exec_tools hơn là tools, trong khi việc này không gây ra bất kỳ vấn đề nào. Sau khi di chuyển xong chức năng, chúng tôi có thể đổi tên exec_tools thành tools. Bạn sẽ nhận được cảnh báo về việc ngừng sử dụng và hướng dẫn di chuyển trước khi điều này diễn ra.

executable

Boolean; optional; nonconfigurable; default is False

Khai báo đầu ra có thể thực thi.

Việc đặt cờ này thành True có nghĩa là đầu ra là một tệp thực thi và có thể chạy bằng lệnh run. Trong trường hợp này, quy tắc tạo phải tạo ra chính xác một đầu ra. Nếu bạn đặt thuộc tính này, run sẽ thử thực thi tệp bất kể nội dung của tệp.

Không hỗ trợ việc khai báo phần phụ thuộc dữ liệu cho tệp thực thi đã tạo.

local

Boolean; optional; default is False

Nếu bạn đặt chính sách này thành True, thì tuỳ chọn này sẽ buộc genrule này chạy bằng chiến lược "local", tức là không có hoạt động thực thi từ xa, không có hộp cát, không có worker liên tục.

Điều này tương đương với việc cung cấp "local" dưới dạng thẻ (tags=["local"]).

message

String; optional

Thông báo tiến trình.

Thông báo tiến trình sẽ được in khi bước tạo bản dựng này được thực thi. Theo mặc định, thông báo là "Đang tạo đầu ra" (hoặc một nội dung nào đó không tương đương) nhưng bạn có thể cung cấp một thông báo cụ thể hơn. Hãy sử dụng thuộc tính này thay vì echo hoặc các câu lệnh in khác trong lệnh cmd, vì điều này cho phép công cụ xây dựng kiểm soát việc các thông báo tiến trình đó có được in hay không.

output_licenses

Licence type; optional

Xem common attributes
output_to_bindir

Boolean; optional; nonconfigurable; default is False

Nếu bạn đặt chính sách này thành True, thì tuỳ chọn này sẽ khiến các tệp đầu ra được ghi vào thư mục bin thay vì thư mục genfiles.

tools

List of labels; optional

Danh sách các phần phụ thuộc của công cụ đối với quy tắc này. Xem định nghĩa về phần phụ thuộc để biết thêm thông tin.

Hệ thống xây dựng đảm bảo xây dựng các điều kiện tiên quyết này trước khi chạy lệnh gen thống. Các điều kiện tiên quyết này được xây dựng bằng cấu hình máy chủ lưu trữ, vì các điều kiện tiên quyết này được thực thi trong quá trình tạo bản dựng. Bạn có thể lấy đường dẫn của một mục tiêu tools riêng lẻ //x:y bằng cách sử dụng $(location //x:y).

Mọi *_binary hoặc công cụ do cmd thực thi đều phải xuất hiện trong danh sách này (không phải trong srcs) để đảm bảo được tạo trong đúng cấu hình.

test_suite

test_suite(name, compatible_with, deprecation, distribs, features, licenses, restricted_to, tags, target_compatible_with, testonly, tests, visibility)

test_suite xác định một tập hợp các chương trình kiểm thử được coi là "hữu ích" đối với con người. Điều này cho phép dự án xác định các tập hợp kiểm thử, chẳng hạn như "các kiểm thử bạn phải chạy trước khi đăng ký", "các kiểm thử căng thẳng của dự án của chúng tôi" hoặc "tất cả các kiểm thử nhỏ". Lệnh blaze test tuân theo kiểu tổ chức này: Đối với một lệnh gọi như blaze test //some/test:suite, trước tiên, Blaze sẽ liệt kê tất cả mục tiêu kiểm thử có trong mục tiêu //some/test:suite theo cách bắc cầu (chúng tôi gọi đây là "bản mở rộng test_suite"), sau đó Blaze sẽ tạo và kiểm thử các mục tiêu đó.

Ví dụ

Một bộ kiểm thử để chạy mọi bài kiểm thử nhỏ trong gói hiện tại.

test_suite(
    name = "small_tests",
    tags = ["small"],
)

Một bộ kiểm thử chạy một tập hợp kiểm thử được chỉ định:

test_suite(
    name = "smoke_tests",
    tests = [
        "system_unittest",
        "public_api_unittest",
    ],
)

Một bộ kiểm thử để chạy tất cả các kiểm thử trong gói hiện tại và đảm bảo không bị ổn định.

test_suite(
    name = "non_flaky_test",
    tags = ["-flaky"],
)

Đối số

Thuộc tính
name

Name; required

Tên duy nhất cho mục tiêu này.

tags

List of strings; optional; nonconfigurable

Danh sách các thẻ văn bản như "nhỏ" hoặc "cơ sở dữ liệu" hoặc "-không ổn định". Thẻ có thể là bất kỳ chuỗi hợp lệ nào.

Những thẻ bắt đầu bằng ký tự "-" được coi là thẻ phủ định. Ký tự "-" trước đó không được coi là một phần của thẻ, do đó, thẻ "-nhỏ" sẽ khớp với kích thước "nhỏ" của kiểm thử. Tất cả các thẻ khác được coi là thẻ khẳng định.

(Không bắt buộc) Để làm cho các thẻ khẳng định rõ ràng hơn, các thẻ cũng có thể bắt đầu bằng ký tự "+". Ký tự này sẽ không được đánh giá là một phần trong văn bản của thẻ. Nó chỉ giúp người dùng dễ dàng đọc sự phân biệt tích cực và tiêu cực.

Chỉ những quy tắc kiểm thử khớp với tất cả thẻ khẳng định và không có thẻ phủ định nào mới được đưa vào bộ kiểm thử. Xin lưu ý rằng điều này không có nghĩa là việc kiểm tra lỗi cho các phần phụ thuộc trên các chương trình kiểm thử đã lọc ra sẽ bị bỏ qua; các phần phụ thuộc trên các chương trình kiểm thử bị bỏ qua vẫn cần phải hợp pháp (ví dụ: không bị chặn bởi các giới hạn về chế độ hiển thị).

Từ khoá thẻ manual được xử lý khác với cách nêu trên bằng cách "mở rộng test_suite" do lệnh blaze test thực hiện trên các lệnh gọi liên quan đến mẫu mục tiêu ký tự đại diện. Ở đó, những mục tiêu test_suite được gắn thẻ "thủ công" sẽ được lọc ra (và do đó không được mở rộng). Hành vi này nhất quán với cách blaze buildblaze test xử lý các mẫu mục tiêu ký tự đại diện nói chung. Xin lưu ý rằng điều này khác với hành vi của blaze query 'tests(E)', vì các bộ luôn được mở rộng bằng hàm truy vấn tests, bất kể thẻ manual là gì.

Xin lưu ý rằng size của kiểm thử được xem là một thẻ để lọc.

Nếu cần một test_suite chứa các thử nghiệm với các thẻ loại trừ lẫn nhau (ví dụ: tất cả các thử nghiệm vừa và nhỏ), bạn sẽ phải tạo 3 quy tắc test_suite: một cho tất cả các thử nghiệm nhỏ, một cho tất cả các thử nghiệm trung bình và một bao gồm hai quy tắc trên.

tests

List of labels; optional; nonconfigurable

Danh sách bộ kiểm thử và mục tiêu kiểm thử cho mọi ngôn ngữ.

Mọi *_test đều được chấp nhận tại đây, bất kể ngôn ngữ. Tuy nhiên, không có mục tiêu *_binary nào được chấp nhận, ngay cả khi chúng tình cờ chạy một kiểm thử. Việc lọc theo tags được chỉ định chỉ được thực hiện cho các chương trình kiểm thử được liệt kê trực tiếp trong thuộc tính này. Nếu thuộc tính này chứa các test_suite, các chương trình kiểm thử bên trong các chương trình kiểm thử đó sẽ không được lọc bằng test_suite này (chúng được coi là đã được lọc).

Nếu thuộc tính tests chưa được chỉ định hoặc để trống thì theo mặc định, quy tắc sẽ bao gồm tất cả các quy tắc kiểm thử trong tệp BUILD hiện tại nhưng chưa được gắn thẻ là manual. Các quy tắc này vẫn đang áp dụng bộ lọc tag.