Quy tắc chung

Báo cáo sự cố Xem nguồn

Quy tắc

bí danh

Xem nguồn quy tắc
alias(name, actual, compatible_with, deprecation, features, restricted_to, tags, target_compatible_with, testonly, visibility)

Quy tắc alias tạo ra một tên khác cho quy tắc.

Bí danh 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ó nội dung khai báo chế độ hiển thị riêng. Trong mọi khía cạnh khác, quy tắc này hoạt động giống như quy tắc mà tệp tham chiếu (ví dụ: chỉ kiểm thử trên bí danh sẽ bị bỏ qua; việc chỉ kiểm thử quy tắc được tham chiếu sẽ được sử dụng) với một số ngoại lệ nhỏ:

  • Các thử nghiệm sẽ không chạy nếu bí danh của chúng được đề cập trên dòng lệnh. Để xác định một bí danh chạy thử nghiệm được tham chiếu, hãy sử dụng quy tắc test_suite có một mục tiêu duy nhất trong thuộc tính tests.
  • Khi xác định các nhóm môi trường, các bí danh đối với các quy tắc environment sẽ không được hỗ trợ. Chúng 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 đến. Đây không cần phải là một quy tắc mà cũng có thể là một tệp đầu vào.

cài đặt cấu hình

Xem nguồn quy tắc
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 ràng buộc về nền tảng) với mục đích kích hoạt các thuộc tính có thể định cấu hình. Vui lòng xem cách 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ụ

Đoạn mã sau khớp với bất kỳ bản dựng nào đặt --compilation_mode=opt hoặc -c opt (tức là rõ ràng tại dòng lệnh hoặc hoàn toàn từ tệp .bazelrc):

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

Mục sau đây khớp với bất kỳ bản dựng nào nhắm mục tiêu ARM và áp dụng định nghĩa tùy chỉnh FOO=bar (ví dụ: bazel build --cpu=arm --define FOO=bar ...):

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

Phần sau khớp với bất kỳ bản dựng nào đặt cờ do người dùng xác định --//custom_flags:foo=1 (ở dòng lệnh một cách rõ ràng hoặc trực tiếp từ tệp .bazelrc):

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

Phần sau khớp với bất kỳ bản dựng nào nhắm mục tiêu một nền tảng có kiến trúc x86_64 và glibc phiên bản 2.25, giả sử sự tồn tại của constraint_value với 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 hai giá trị này.

  config_setting(
      name = "64bit_glibc_2_25",
      constraint_values = [
          "@platforms//cpu:x86_64",
          "//example:glibc_2_25",
      ]
  )
  
Trong tất cả những trường hợp này, có thể cấu hình thay đổi trong bản dựng, ví dụ: nếu mục tiêu cần được xây dựng cho một nền tảng khác với nền tảng phụ thuộc, thì ngay cả khi config_setting không khớp với cờ dòng lệnh cấp cao nhất, thì 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ợ biểu mẫu viết tắt (ví dụ: --compilation_mode so với -c), định nghĩa values phải sử dụng biểu mẫu đầy đủ. Các lệnh gọi này tự động so khớp lệnh gọi bằng một trong hai biểu mẫu.
  • Nếu một cờ nhận nhiều giá trị (như --copt=-Da --copt=-Db hoặc một loại cờ danh sách larlark), values = { "flag": "a" } sẽ khớp nếu "a" có mặt ở bất kỳ đâu trong danh sách thực tế.

    values = { "myflag": "a,b" } hoạt động theo cách tương tự: thuộc tính này khớp với --myflag=a --myflag=b, --myflag=a --myflag=b --myflag=c, --myflag=a,b--myflag=c,b,a. Ngữ nghĩa chính xác sẽ khác nhau 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ị sau). Nhưng --ios_multi_cpus (đối với quy tắc của Apple) : -ios_multi_cpus=a,bios_multi_cpus=a --ios_multi_cpus=b đều tạo ra ["a", "b"]. Hãy kiểm tra định nghĩa cờ và kiểm tra kỹ các điều kiện của bạn để xác minh chính xác kỳ vọng.

  • Nếu bạn cần xác định những điều kiện không được mô hình hoá bằng cờ bản dựng tích hợp sẵn, hãy sử dụng cờ Starlark xác định. Bạn cũng có thể sử dụng --define. Tuy nhiên, bạn nên sử dụng dịch vụ hỗ trợ kém hơn và chúng tôi không khuyên bạn làm như vậy. Xem tại đây để thảo luận thêm.
  • Tránh lặp lại định nghĩa config_setting giống hệt nhau trong các gói khác nhau. Thay vào đó, hãy tham chiếu đến một config_setting phổ biến được xác định trong gói chính tắc.
  • Bạn có thể dùng values, define_valuesconstraint_values trong mọi cách kết hợp trong cùng một config_setting, nhưng bạn phải đặt ít nhất một tuỳ chọn cho mọi 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 tối thiểu constraint_values mà nền tảng mục tiêu phải chỉ định để khớp với config_setting này. (Nền tảng thực thi không được xem xét tại đây.) Mọi giá trị ràng buộc bổ sung mà nền tảng đã bỏ qua. Hãy xem bài viết Các thuộc tính có thể định cấu hình cho bản dựng để biết thông tin chi tiết.

Trong trường hợp hai config_setting khớp với nhau trong cùng một select, thuộc tính này không được xem xét để xác định xem một trong các config_setting có phải là chuyên môn của Google hay không. Nói cách khác, một config_setting sẽ không thể khớp với một nền tảng mạnh hơn 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 là KEY=VALgiá trị từ góc nhìn của cờ Bazel.

Điều đó có nghĩa 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 2 lần trong từ điển. Thuộc tính này giải quyết được vấn đề đó:

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

khớp 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ể kết hợp tự do 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 đối với 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 trong khi cờ tích hợp được tham chiếu dưới dạng chuỗi tuỳ ý.

values

Dictionary: String -> String; optional; nonconfigurable

Bộ giá trị cấu hình khớ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 cấu hình đó trong câu lệnh select. Thao tác này được coi là "khớp" lệnh gọi Bazel nếu đối với mỗi mục nhập trong từ điển, cấu hình của lệnh gọi 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 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, hãy chỉ định các giá trị cấu hình dưới dạng cờ bản dựng (không có "--" trước đó). Nhưng hãy lưu ý rằng hai giá trị này không giống nhau. Lý do là các mục tiêu có thể được tạo 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 thực thi khớp với giá trị của --host_cpu, chứ không phải --cpu. Vì vậy, các bản sao khác nhau 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 lệnh gọi đó.

Nếu cờ không được đặt rõ ràng tại dòng lệnh, giá trị mặc định sẽ được sử dụng. Nếu một khoá 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ì việc khớp sẽ xảy ra nếu bất kỳ chế độ cài đặt nào trong số đó khớp.

nhóm tệp

Xem nguồn quy tắc
filegroup(name, srcs, data, compatible_with, deprecation, distribs, features, licenses, output_group, restricted_to, tags, target_compatible_with, testonly, visibility)

Sử dụng filegroup để đặt tên thuận tiện cho tập hợp mục tiêu. Sau đó, bạn có thể tham chiếu đến 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. Phần sau không có âm thanh vì hệ thống xây dựng không có đầy đủ kiến thức về tất cả các tệp bên dưới thư mục, do đó có thể không tạo lại được khi những tệp này thay đổi. Khi 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 hai 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 để đi kèm thư mục dữ liệu kiểm thử:

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 đến filegroup bằng một nhãn từ bất kỳ quy tắc nào:

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 mục tiêu là thành viên của nhóm tệp.

Thông thường, bạn nên dùng kết quả của 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 mà quy tắc này cần 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. Xem mụ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 mà từ đó thu thập các cấu phần phần mềm từ nguồn. Nếu thuộc tính này được chỉ định, cấu phần phần mềm từ nhóm đầu ra 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ác cấu phần phần mềm đầu ra của một mục tiêu, được xác định trong cách triển khai quy tắc đó.

truy vấn tạo thế

Xem nguồn quy tắc
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 một truy vấn được chỉ định bằng Ngôn ngữ truy vấn linh hoạt và kết quả được chuyển thành 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 việc đóng tạm thời của các mục tiêu được 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ực hiện được trong quá trình thực thi nếu strict không được chỉ định hoặc đúng (nếu strict sai, các mục tiêu nằm ngoài phạm vi sẽ chỉ bị bỏ qua kèm theo cảnh báo). Cách dễ nhất để đảm bảo việc này không xảy ra là đề cập đến cùng một 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à không được phép chứa các truy vấn chứa thông số mục tiêu ký tự đại diện (ví dụ: //pkg:* hoặc //pkg:all). Lý do có hai phần tử: thứ nhất, vì genquery phải chỉ định phạm vi để ngăn các mục tiêu bên ngoài việc đóng truy vấn chuyển tiếp nhằm tác động đến đầu ra của truy vấn; và thứ hai, vì các tệp BUILD không hỗ trợ các phần phụ thuộc ký tự đại diện (ví dụ: deps=["//a/..."] không được phép).

Đầu ra của truy vấn thế hệ mới được sắp xếp bằng cách sử dụng --order_output=full để thực thi đầu ra xác định.

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

Ví dụ

Ví dụ này sẽ viết danh sách các nhãn trong phần đóng cửa 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 cần 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 tại đâ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 //:b mục tiêu.
opts

List of strings; optional

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

List of labels; 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 ngoài mục tiêu đóng cửa bắc cầu.
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 phạm vi đóng bắc cầu sẽ không tạo được. Nếu giá trị là false thì Bazel sẽ in một cảnh báo và bỏ qua mọi đường dẫn truy vấn dẫn ra ngoài phạm vi, trong khi hoàn tất phần còn lại của truy vấn.

tạo quy tắc

Xem nguồn quy tắc
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.

Genrules là các quy tắc tạo bản dựng chung mà bạn có thể sử dụng nếu không có quy tắc cụ thể cho tác vụ. Ví dụ: bạn có thể chạy một dòng giới thiệu Bash. Tuy nhiên, nếu bạn cần biên dịch tệp C++, hãy tuân thủ các quy tắc cc_* hiện có, vì bạn đã thực hiện tất cả những công việc khó khăn.

Lưu ý rằng genrule yêu cầu một shell để diễn giải đối số lệnh. Bạn cũng có thể dễ dàng tham chiếu các chương trình tuỳ ý có sẵn trên PATH, tuy nhiên, điều này khiến lệnh không có tính khép kín và có thể không tái tạo được. Nếu bạn chỉ cần chạy một công cụ duy nhất, hãy cân nhắc sử dụng run_binary.

Không sử dụng quy tắc tạo gen để chạy kiểm thử. Có các chính sách đặc biệt cho quá trình kiểm thử và kết quả kiểm thử, bao gồm cả chính sách về bộ nhớ đệm và các biến môi trường. Các thử nghiệm thường 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 gen được thực thi trong bản dựng và trên cấu trúc thực thi (hai có thể khác nhau). Nếu bạn cần một quy tắc kiểm thử đa năng, hãy sử dụng sh_test.

Những điểm cần cân nhắc khi 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 tạo gen chạy trong quá trình tạo bản dựng, nhưng kết quả của chúng thường được sử dụng sau bản dựng để triển khai hoặc thử nghiệm. Hãy xem xét ví dụ về việc biên dịch mã C cho một 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 dùng để xây dựng mã, nhưng bản thân trình biên dịch C (nếu được biên dịch từ nguồn) thì phải làm như vậy.

Hệ thống xây dựng sử dụng cấu hình thực thi để mô tả(các) máy mà bản dựng sẽ chạy 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ẽ được chạy trên đó. Công cụ này cung cấp các tuỳ chọn để định cấu hình từng thư mục và tách riêng các tệp tương ứng thành các thư mục riêng biệt để tránh xung đột.

Đối với các quy tắc tạo hệ thống, hệ thống xây dựng đảm bảo rằng các phần phụ thuộc được xây dựng một cách phù hợp: srcs được xây dựng (nếu cần) cho cấu hình target, tools được xây dựng cho cấu hình exec và kết quả được coi là dành cho cấu hình target. Nó cũng cung cấp các biến "Make" mà các lệnh genrule có thể chuyển đến các công cụ tương ứng.

Mục đích là để genrule không xác định thuộc tính deps: các quy tắc tích hợp khác sử 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, nhưng mức độ tự động hoá này không thể áp dụng cho các quy tắc tạo gen. Genrules chỉ hoạt động ở cấp độ tệp và runfiles.

Các trường hợp đặc biệt

Biên dịch thực thi: trong một số trường hợp, hệ thống xây dựng cần chạy quy tắc tạo sao cho kết quả cũng có thể được thực thi trong quá trình tạo. Ví dụ: nếu một genrule xây dựng một số trình biên dịch tuỳ chỉnh mà sau đó được một genrule khác sử dụng, thì trình biên dịch đầu tiên phải tạo ra kết quả cho cấu hình thực thi vì đó là nơi trình biên dịch sẽ chạy trong genrule khác. Trong trường hợp này, hệ thống xây dựng sẽ tự động thực hiện đúng việc: hệ thống sẽ tạo srcsouts của quy tắc tạo gen đầu tiên cho cấu hình thực thi thay vì cấu hình mục tiêu. Hãy 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 trình biên dịch JDK hoặc C++, hệ thống xây dựng cung cấp một tập hợp các biến để sử dụng. Hãy xem biến"Tạo" để biết thông tin chi tiết.

Môi trường Gengen

Lệnh genrule được thực thi bởi một vỏ Bash được định cấu hình để không thực hiện được khi lệnh hoặc một 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 sẽ 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 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 sẽ không được chuyển qua lệnh của genrule. Tuy nhiên, Bazel (nhưng không phải Blaze) truyền giá trị 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 trên bản dựng tiếp theo.

Lệnh genrule 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 lệnh đó, mặc dù thao tác 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 tạo mọi thư mục mẹ cần thiết trước khi chạy quy tắc tạo gen. Thao tác này cũng xoá mọi tệp đầu ra trong trường hợp xảy ra lỗi.

Lời khuyên chung

  • Đảm bảo rằng các công cụ chạy bằng quy tắc gen mang tính quyết định và khép kín. Họ không nên viết dấu thời gian vào kết quả của mình và nên sử dụng thứ tự ổn định cho các tập hợp và bản đồ, cũng như chỉ viết 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 xây dựng không mong muốn (Bazel không tạo lại quy tắc mà bạn nghĩ là sẽ có) và làm giảm hiệu suất bộ nhớ đệm.
  • Sử dụng $(location) một cách rộng rãi cho các kết quả, công cụ và nguồn. Do sự phân tách của các tệp đầu ra cho các cấu hình khác nhau, các quy tắc tạo gen không thể dựa vào đường dẫn tuyệt đối được mã hoá cứng và/hoặc tuyệt đối.
  • 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 nơi. Nếu quy tắc chung phức tạp, hãy cân nhắc triển khai quy tắc này 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 tra.
  • Đảm bảo rằng mã thoát chỉ ra chính xác thành công hoặc không thành công của quy tắc tạo gen.
  • Không viết thông báo thông tin cho stdout hoặc stderr. Mặc dù hữu ích khi gỡ lỗi, nhưng cách làm này có thể dễ dàng trở thành tiếng ồn; một quy tắc tạo thành công sẽ im lặng. Mặt khác, quy tắc tạo gen không thành công sẽ tạo ra thông báo lỗi tốt.
  • $$ 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 các đường 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 do genrules tạo ra và việc kiểm tra phần phụ thuộc của các thư mục sẽ không có âm thanh.
  • Khi tham chiếu genrule trong các quy tắc khác, bạn có thể sử dụng nhãn của genrule hoặc nhãn của từng tệp đầu ra. Đôi khi, một phương pháp dễ đọc hơn, đôi khi phương thức khác: tham chiếu kết quả theo tên trong srcs của quy tắc tiêu thụ sẽ tránh việc vô tình chọn các kết quả khác của quy tắc chung, nhưng có thể tẻ nhạt nếu quy tắc đó tạo ra nhiều kết quả đầu ra.

Ví dụ

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

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

Ví dụ sau đây cho biết 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ì các lệnh $(location) rõ ràng cũng sẽ hoạt động; ví dụ này sử dụng nội dung sau để minh họa.

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 khảo quy tắc này theo tên trong phần srcs hoặc deps của các quy tắc BUILD khác. Nếu quy tắc tạo các tệp nguồn, 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ư các tệp nguồ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; 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 những điều kiện tiên quyết này được xây dựng trước khi chạy lệnh genrule; chúng được xây dựng bằng cùng cấu hình với yêu cầu bản dựng ban đầu. Tên của các tệp trong những điều kiện tiên quyết này có sẵn cho lệnh dưới dạng 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 $(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 bằng 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 hiểu là tương đối so với gói.

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

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

cmd

String; optional

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

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

cmd_bash

String; optional

Lệnh Bash để chạy.

Thuộc tính này có mức độ ưu tiên cao hơn cmd. Lệnh này được mở rộng và chạy giống hệ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 hoạt động giống 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 với cmd.exe /c với các đối số mặc định sau:
    • /S – bỏ dấu ngoặc kép đầu tiên và cuối cùng rồi thực thi mọi thứ khác như hiện tại.
    • /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ì hoãn
    • /D – bỏ qua các mục đă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 hoạt động 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 với powershell.exe /c.

Để giúp Powershell dễ sử dụng hơn và ít xảy ra lỗi hơn, chúng tôi 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 genrule.

  • Set-ExecutionPolicy -Scope CurrentUser RemoteSigned – cho phép chạy các tập lệnh chưa được ký.
  • $errorActionPreference='Stop' – Trong trường hợp có nhiều lệnh được phân tách bằng ;, thao tác này sẽ thoát ngay lập tức nếu Powershell CmdLet không hoạt động, nhưng NOT 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

Không dùng nữa. Thay vào đó, hãy sử dụng tools.

Trong một khoảng thời gian, exec_toolstools đã hoạt động theo cách khác nhau, nhưng hiện tại các mã này tương đương nhau và nhóm Blaze sẽ di chuyển tất cả các mục đích sử dụng của exec_tools sang tools.

executable

Boolean; optional; nonconfigurable; default is False

Khai báo kết quả đầu ra là có thể thực thi.

Việc đặt cờ này thành Đúng có nghĩa là đầu ra là một tệp thực thi và có thể chạy bằng lệnh run. Gengen phải tạo chính xác một kết quả trong trường hợp này. 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 nó là gì.

Không hỗ trợ khai báo các 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 Đúng, thì tùy chọn này sẽ buộc genrule này phải chạy bằng chiến lược "địa phương", nghĩa là không có quá trình thực thi từ xa, không có hộp cát, không có trình chạy cố định.

Đ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.

Một thông báo tiến trình sẽ được in khi bước xây dựng này được thực thi. Theo mặc định, thông báo sẽ là "Đang tạo đầu ra" (hoặc nội dung nào đó tương tự nhau), nhưng bạn có thể cung cấp 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ì thuộc tính 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 như vậy 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 Đúng, tuỳ chọn này sẽ ghi các tệp đầu ra 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ông cụ cho quy tắc này. Hã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 những điều kiện tiên quyết này được xây dựng trước khi chạy lệnh genrule; chúng được xây dựng bằng cách sử dụng exec cấu hình, vì các công cụ này được thực thi như một phần của 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).

Bất kỳ *_binary hoặc công cụ nào do cmd thực thi phải xuất hiện trong danh sách này, không phải trong srcs, để đảm bảo rằng chúng được xây dựng ở đúng cấu hình.

bộ_thử_nghiệm

Xem nguồn quy tắc
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 kiểm thử được coi là "hữu ích" với con người. Điều này cho phép các dự án xác định các tập hợp kiểm thử, chẳng hạn như "kiểm thử mà bạn phải chạy trước khi kiểm tra", "kiểm thử căng thẳng trong dự án" hoặc "tất cả kiểm thử nhỏ". Lệnh blaze test tuân theo loại tổ chức này: Đối với lệnh gọi như blaze test //some/test:suite, trước tiên, Blaze liệt kê tất cả mục tiêu kiểm thử được đưa vào mục tiêu //some/test:suite (chúng tôi gọi đây là "mở rộng test_ suite"), sau đó Blaze xây dựng và kiểm thử các mục tiêu đó.

Ví dụ

Một bộ kiểm thử chạy tất cả các kiểm thử nhỏ trong gói hiện tại.

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

Bộ kiểm thử chạy một tập hợp kiểm thử cụ thể:

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 không ổ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ư "small" hoặc "database" hoặc "-flaky". Thẻ có thể là bất kỳ chuỗi hợp lệ nào.

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ẻ, vì vậy, thẻ bộ "-small" khớp với kích thước "nhỏ" của thử nghiệm. Tất cả các thẻ khác được coi là thẻ dương.

Nếu muốn làm cho các thẻ tích cực trở nên rõ ràng hơn, thì thẻ cũng có thể bắt đầu bằng ký tự "+", ký tự này sẽ không được đánh giá trong văn bản của thẻ. Hệ thống này chỉ đơn giản là dễ đọc sự khác 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ẻ tiêu cực 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 bỏ qua quá trình kiểm tra lỗi đối với các phần phụ thuộc trên các kiểm thử bị lọc bỏ sẽ phụ thuộc vào các kiểm thử bị bỏ qua vẫn cần phải hợp pháp (ví dụ: không bị các quy tắc ràng buộc hiển thị).

Từ khoá thẻ manual được xử lý theo cách khác với cách nêu trên trong "mở rộng test_ suite" do lệnh blaze test thực hiện đối với các lệnh gọi liên quan đến các mẫu mục tiêu ký tự đại diện. Ở đó, các mục tiêu test_suite được gắn thẻ "thủ công" sẽ bị lọc ra (và do đó không được mở rộng). Hành vi này phù hợp 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 cách hoạt động của blaze query 'tests(E)' vì các bộ ứng dụng luôn mở rộng bằng hàm truy vấn tests, bất kể thẻ manual là gì.

Lưu ý rằng size của kiểm thử được xem là thẻ nhằm mục đích lọc.

Nếu cần một test_suite chứa các kiểm thử có thẻ loại trừ lẫn nhau (ví dụ: tất cả kiểm thử nhỏ và trung bình), bạn sẽ phải tạo ba quy tắc test_suite: một cho tất cả kiểm thử nhỏ, một cho tất cả kiểm thử trung bình và một cho hai kiểm thử trước đó.

tests

List of labels; optional; nonconfigurable

Danh sách các bộ thử nghiệm và mục tiêu thử nghiệm của ngôn ngữ bất kỳ.

Mọi *_test đều được chấp nhận tại đây, bất kể ngôn ngữ. Tuy nhiên, chúng tôi không chấp nhận mục tiêu *_binary, ngay cả khi các mục tiêu đó dùng để chạy thử nghiệm. Bạn chỉ có thể lọc theo tags được chỉ định cho các thử nghiệm đượ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 test_suite, thì các kiểm thử bên trong các kiểm thử đó sẽ không bị test_suite này lọc (được coi là đã bị lọc).

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