Quy tắc chung

Báo cáo vấn đề Xem nguồn Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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 mà quy tắc có thể được gọi.

Việc đặt biệt hiệu chỉ hoạt động đối với các mục tiêu "thông thường". Cụ thể, bạn không thể đặt bí danh cho package_grouptest_suite.

Việc đặt bí danh có thể hữu ích trong các kho lưu trữ lớn, nơi việc đổi tên một mục tiêu sẽ yêu cầu bạn thực hiện các thay đổi đối với nhiều tệp. Bạn cũng có thể sử dụng quy tắc biệt hiệu để lưu trữ một lệnh gọi hàm select nếu muốn dùng lại logic đó cho nhiều mục tiêu.

Quy tắc bí danh có khai báo khả năng hiển thị riêng. Về mọi mặt khác, quy tắc này hoạt động giống như quy tắc mà nó tham chiếu (ví dụ: testonly trên bí danh sẽ bị bỏ qua; thay vào đó, thuộc tính testonly của quy tắc được tham chiếu sẽ được dùng) với một số trường hợp ngoại lệ nhỏ:

  • Các kiểm thử 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 kiểm thử được tham chiếu, hãy sử dụng quy tắc test_suite với một đích duy nhất trong thuộc tính tests.
  • Khi xác định nhóm môi trường, hệ thống không hỗ trợ các bí danh cho quy tắc environment. Các tuỳ chọn 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

Tên; bắt buộc

Tên riêng cho mục tiêu này.

actual

Nhãn; bắt buộc

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

config_setting

Xem nguồn quy tắc
config_setting(name, constraint_values, define_values, deprecation, distribs, features, flag_values, licenses, tags, testonly, values, visibility)

So khớp 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 của nền tảng) cho 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 select để biết cách sử dụng quy tắc này và Configurable attributes để biết thông tin tổng quan về tính năng chung.

Ví dụ

Sau đây là mọi bản dựng đặt --compilation_mode=opt hoặc -c opt (một cách rõ ràng tại dòng lệnh hoặc một cách ngầm ẩn từ các tệp .bazelrc):

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

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

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

Sau đây là 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 một cách ngầm định từ các tệp .bazelrc):

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

Sau đây khớ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ó một 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 nền tảng đó xác định các giá trị ràng buộc bổ sung 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ả các trường hợp này, có thể cấu hình sẽ thay đổi trong quá trình tạo, ví dụ: nếu cần tạo một mục tiêu cho một nền tảng khác với nền tảng phụ thuộc của mục tiêu đó. Điều này có nghĩa là ngay cả khi config_setting không khớp với các 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 tạo.

Ghi chú

  • Hãy xem phần select để 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ác cờ hỗ trợ dạng viết tắt (ví dụ: --compilation_mode so với -c), định nghĩa values phải sử dụng dạng đầy đủ. Các lệnh gọi này sẽ tự động khớp bằng cách sử dụ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 một cờ Starlark có kiểu danh sách), values = { "flag": "a" } sẽ khớp nếu "a" xuất hiện ở bất kỳ vị trí nào trong danh sách thực tế.

    values = { "myflag": "a,b" } hoạt động theo cách tương tự: điều 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 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ị trước nhưng không khớp với giá trị sau). 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 định nghĩa cờ và kiểm tra kỹ các điều kiện để xác minh kỳ vọng chính xác.

  • Nếu bạn cần xác định các điều kiện không được mô hình hoá bằng cờ bản dựng tích hợp, hãy sử dụng cờ do Starlark xác định. Bạn cũng có thể sử dụng --define, nhưng cách này có khả năng hỗ trợ kém hơn và không nên dùng. Hãy xem tại đây để biết thêm thông tin thảo luận.
  • Tránh lặp lại các đị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 chung được xác định trong một gói chuẩn.
  • values, define_valuesconstraint_values có thể được dùng theo mọi tổ hợp trong cùng một config_setting nhưng bạn phải đặt ít nhất một trong số các tham số này cho mọi config_setting nhất định.

Đối số

Thuộc tính
name

Tên; bắt buộc

Tên riêng cho mục tiêu này.

constraint_values

Danh sách nhãn; không thể định cấu hình; mặc định là []

Tập hợp tối thiểu gồm 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 ở đây.) Mọi giá trị ràng buộc bổ sung mà nền tảng có đều 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 cả 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 cho mục đích xác định xem một trong các config_setting có phải là một chuyên môn của config_setting còn lại hay không. Nói cách khác, một config_setting không thể phù hợp với một nền tảng hơn một nền tảng khác.

define_values

Từ điển: String -> String; nonconfigurable; mặc định là {}

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

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

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

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

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

--define vẫn có thể xuất hiện trong values bằng cú pháp cờ thông thường và có thể kết hợp thoải mái 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

Từ điển: label -> String; nonconfigurable; mặc định là {}

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, trong khi cờ tích hợp được tham chiếu dưới dạng các chuỗi tuỳ ý.

values

Từ điển: String -> String; nonconfigurable; mặc định là {}

Tập hợp các 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 quy tắc đó trong một câu lệnh select. Thao tác này được coi là "khớp" một lệnh gọi Bazel nếu đối với mọi mục trong từ điển, cấu hình của mục đó khớp với giá trị dự kiến của mục. 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 theo mục tiêu.

Để thuận tiện, các giá trị cấu hình được chỉ định dưới dạng cờ xây dựng (không có "--" ở phía 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 tạo trong nhiều cấu hình trong cùng một bản dựng. Ví dụ: "cpu" trong cấu hình thực thi khớp với giá trị của --host_cpu, chứ không phải --cpu. Do đó, các thực thể 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 thực thể đó.

Nếu bạn không đặt rõ ràng một cờ tại dòng lệnh, thì giá trị mặc định của cờ đó sẽ được sử dụng. Nếu một khoá xuất hiện nhiều lần trong từ điển, thì chỉ phiên bản cuối cùng được 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ì sẽ xảy ra một lượt khớp nếu bất kỳ chế độ cài đặt nào trong số đó khớp.

filegroup

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 một nhóm mục tiêu. Sau đó, bạn có thể tham chiếu các 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 đến các thư mục. Cách thứ hai không ổn định vì hệ thống xây dựng không có đầy đủ thông tin về tất cả các tệp bên dưới thư mục, nên hệ thống có thể không xây dựng lại khi các 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 2 tệp nguồn, hãy làm như sau

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

Hoặc sử dụng glob để tìm kiếm một 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 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

Tên; bắt buộc

Tên riêng cho mục tiêu này.

srcs

Danh sách nhãn; mặc định là []

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

Bạn thường dùng kết quả của biểu thức glob cho giá trị của thuộc tính srcs.

data

Danh sách nhãn; mặc định là []

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 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 quy tắc đó 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ào và sử dụng các tệp dữ liệu.

output_group

Chuỗi; giá trị mặc định là ""

Nhóm đầu ra mà từ đó thu thập các 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ủa cá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 đó.

genquery

Xem nguồn quy tắc
genquery(name, deps, data, compatible_with, compressed_output, 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 trong ngôn ngữ truy vấn Blaze và kết xuất kết quả vào một tệp.

Để duy trì bản dựng nhất quán, truy vấn chỉ được phép truy cập vào bao đóng bắc cầu 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 có giá trị true (nếu strict có giá trị false, các mục tiêu 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 điều này không xảy ra là đề cập đến các nhãn tương tự 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 chứa thông số mục tiêu ký tự đại diện (ví dụ: //pkg:* hoặc //pkg:all) không được phép ở đây. Có hai lý do cho việc này: thứ nhất, vì genquery phải chỉ định một phạm vi để ngăn các mục tiêu bên ngoài bao đóng bắc cầu của truy vấn ảnh hưở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 có ký tự đại diện (ví dụ: deps=["//a/..."] không được phép).

Đầu ra của genquery được sắp xếp theo thứ tự từ điển để thực thi đầu ra xác định, ngoại trừ --output=graph|minrank|maxrank hoặc khi somepath được dùng làm hàm cấp cao nhất.

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 nhãn trong bao đóng của mục tiêu đã 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

Tên; bắt buộc

Tên riêng cho mục tiêu này.

compressed_output

Boolean; giá trị mặc định là False

Nếu True, đầu ra truy vấn sẽ được ghi ở định dạng tệp GZIP. Bạn có thể dùng chế độ cài đặt này để tránh tình trạng tăng đột biến mức sử dụng bộ nhớ của Bazel khi đầu ra truy vấn dự kiến có kích thước lớn. Bazel đã nén nội bộ các đầu ra truy vấn lớn hơn 220 byte, bất kể giá trị của chế độ cài đặt này. Vì vậy, việc đặt chế độ này thành True có thể không làm giảm heap được giữ lại. Tuy nhiên, thao tác này cho phép Bazel bỏ qua quá trình giải nén khi ghi tệp đầu ra, có thể tốn nhiều bộ nhớ.
expression

Chuỗi; bắt buộc

Truy vấn sẽ được thực thi. Không giống như 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ẽ đề cập đến mục tiêu //:b.
opts

Danh sách các chuỗi; mặc định là []

Các lựa 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 truyền đến bazel query. Một số lựa chọn truy vấn không được phép ở đây: --keep_going, --query_file, --universe_scope, --order_results--order_output. Các lựa chọn không được chỉ định ở đây sẽ có giá trị mặc định giống như trên dòng lệnh của bazel query.
scope

Danh sách nhãn; bắt buộc

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 bao đóng bắc cầu của các mục tiêu này.
strict

Boolean; giá trị mặc định là True

Nếu đúng, những mục tiêu có truy vấn thoát khỏi bao đóng bắc cầu của phạm vi sẽ không thể tạo. Nếu là false, Bazel sẽ in một cảnh báo và bỏ qua mọi đường dẫn truy vấn khiến nó nằm ngoài phạm vi, đồng thời hoàn tất phần còn lại của truy vấn.

genrule

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

Genrule là các quy tắc chung để tạo 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 dòng lệnh Bash. Tuy nhiên, nếu bạn cần biên dịch các tệp C++, hãy tuân thủ các quy tắc cc_* hiện có, vì mọi công việc nặng nhọc đã được thực hiện cho bạn.

Xin 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ó trên PATH, tuy nhiên, điều này khiến lệnh không 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ụ, hãy cân nhắc sử dụng run_binary.

Không sử dụng genrule để chạy kiểm thử. Có những quy định đặc biệt về các bài 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ường, bạn cần chạy các kiểm thử sau khi bản dựng hoàn tất và trên cấu trúc mục tiêu, trong khi genrule được thực thi trong quá trình tạo bản dựng và trên cấu trúc exec (hai cấu trúc này có thể khác nhau). Nếu bạn cần một quy tắc kiểm thử cho mục đích chung, hãy sử dụng sh_test.

Những điều 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ề quy trình biên dịch chéo.

Mặc dù genrules chạy trong quá trình tạo bản dựng, nhưng đầu ra của chúng thường được dùng sau khi tạo 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 một bộ vi điều khiển. Rõ ràng là mã được tạo không thể chạy trên CPU đã dùng để tạo mã đó, nhưng trình biên dịch C (nếu được biên dịch từ nguồn) phải chạy.

Hệ thống xây dựng sử dụng cấu hình exec để mô tả(các) máy mà bản dựng 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 được giả định là sẽ chạy. Công cụ này cung cấp các lựa chọn để định cấu hình từng lựa chọn và phân tách 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 genrule, hệ thống bản dựng đảm bảo rằng các phần phụ thuộc được tạo đúng cách: srcs được tạo (nếu cần) cho cấu hình target, tools được tạo cho cấu hình exec và đầu ra được coi là cho cấu hình target. Công cụ này cũng cung cấp các biến "Make" mà các lệnh genrule có thể truyền đến các công cụ tương ứng.

genrule không xác định thuộc tính deps là có chủ ý: 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 không thể có mức độ tự động hoá này đối với genrule. Genrules hoạt động hoàn toàn ở cấp độ tệp và tệp thực thi.

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

Biên dịch Exec-exec: trong một số trường hợp, hệ thống tạo bản dựng cần chạy genrules để đầu ra cũng có thể được thực thi trong quá trình tạo bản dựng. Ví dụ: nếu một genrule tạo một trình biên dịch tuỳ chỉnh mà sau đó được một genrule khác sử dụng, thì genrule đầu tiên phải tạo ra đầu ra cho cấu hình exec, vì đó là nơi trình biên dịch sẽ chạy trong genrule kia. Trong trường hợp này, hệ thống bản dựng sẽ tự động thực hiện đúng thao tác: hệ thống sẽ tạo srcsouts của genrule đầu tiên cho cấu hình exec 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.

JDK và công cụ C++: để sử dụng một công cụ trong JDK hoặc bộ trình biên dịch 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 "Make" để biết thông tin chi tiết.

Môi trường Genrule

Lệnh genrule được thực thi bằng một trình bao Bash được định cấu hình để không thành công khi một 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ụ tạo thực thi lệnh Bash trong một 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 sẽ không được truyền qua lệnh genrule. Tuy nhiên, Bazel (nhưng không phải Blaze) sẽ truyền 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 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à các lệnh con của chính lệnh đó, mặc dù hiện tại điều này không được thực thi.

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

Ví dụ

Ví dụ này tạo ra 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. "binary" do lệnh này chạy là một tập lệnh perl trong cùng 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 thấy cách sử dụng filegroup và đầu ra của một genrule khác. Xin lưu ý rằng việc sử dụng $(SRCS) thay vì các chỉ thị $(location) rõ ràng cũng sẽ hoạt động; ví dụ này sử dụng chỉ thị sau cho mục đí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

Tên; bắt buộc

Tên riêng cho mục tiêu này.


Bạn có thể tham chiếu 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 tệp nguồn, bạn nên sử dụng thuộc tính srcs.
srcs

Danh sách nhãn; mặc định là []

Danh sách các giá trị đầu vào cho quy tắc này, chẳng hạn như các 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 các đ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 một cấu hình như yêu cầu xây dựng ban đầu. Tên của các tệp trong danh sách đ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 cách sử dụng $(location //x:y) hoặc $<, miễn là đó là mục duy nhất trong srcs.

outs

Danh sách tên tệp; không thể định cấu hình; bắt buộc

Danh sách các tệp do quy tắc này tạo.

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

Nếu cờ executable được đặt, 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í đã xác định trước. Vị trí này có trong cmd bằng cách sử dụng các biến "Make" dành riêng cho genrule ($@, $(OUTS), $(@D) hoặc $(RULEDIR)) hoặc bằng cách sử dụng phương thức thay thế $(location).

cmd

Chuỗi; giá trị mặc định là ""

Lệnh để chạy. Tuỳ thuộc vào $(location) thay thế biến"Make".
  1. Áp dụng phép thay thế $(location) đầu tiên, thay thế tất cả các lần xuất hiện của $(location label)$(locations label) (cũng như các cấu trúc tương tự bằng cách sử dụng các biến liên quan execpath, execpaths, rootpathrootpaths).
  2. Tiếp theo, các biến "Make" (Tạo) sẽ được mở rộng. Xin lưu ý rằng các biến được xác định trước $(JAVA), $(JAVAC)$(JAVABASE) sẽ mở rộng trong cấu hình exec, do đó, các lệnh gọi Java chạy trong một bước xây dựng có thể tải chính xác các thư viện dùng chung 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 của lệnh khác 0, thì lệnh đó được coi là không thành công.
Đây là chế độ dự phòng của cmd_bash, cmd_pscmd_bat, nếu không có chế độ nào trong số này áp dụng.

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ì genrule 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 đề. Điều 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

Chuỗi; giá trị mặc định là ""

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 theo cách giống hệt như thuộc tính cmd.

cmd_bat

Chuỗi; giá trị mặc định là ""

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, với 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 cùng các đối số mặc định sau:
    • /S – xoá dấu ngoặc kép đầu tiên và cuối cùng, đồng thờ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 theo kiểu Windows (có dấu gạch chéo ngược).
cmd_ps

Chuỗi; giá trị mặc định là ""

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, với 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 ta sẽ 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 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 một CmdLet Powershell 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.
executable

Boolean; không thể định cấu hình; mặc định là False

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

Nếu bạn đặt cờ này thành True, tức 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, genrule 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ẽ cố gắng thực thi tệp bất kể nội dung của tệp.

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

local

Boolean; giá trị mặc định là False

Nếu bạn đặt thành True, thì lựa chọn này sẽ buộc genrule chạy bằng chiến lược "cục bộ", tức là khô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" làm thẻ (tags=["local"]).

message

Chuỗi; giá trị mặc định là ""

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

Thông báo tiến trình sẽ được in khi bước tạo này được thực thi. Theo mặc định, thông báo là "Đang tạo đầu ra" (hoặc một thông báo tương tự) 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ì điều này cho phép công cụ tạo kiểm soát việc có in các thông báo tiến trình như vậy hay không.

output_licenses

Loại giấy phép; mặc định là ["none"]

Xem common attributes
output_to_bindir

Boolean; không thể định cấu hình; mặc định là False

Nếu bạn đặt thành True, 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

Danh sách nhãn; mặc định là []

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 các đ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ấu hình exec, vì các công cụ này được thực thi trong quá trình xây dựng. Bạn có thể lấy đường dẫn của từng mục tiêu tools //x:y bằng cách sử dụng $(location //x:y).

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

starlark_doc_extract

Xem nguồn quy tắc
starlark_doc_extract(name, deps, src, data, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, features, licenses, render_main_repo_name, restricted_to, symbol_names, tags, target_compatible_with, testonly, visibility)

starlark_doc_extract() trích xuất tài liệu cho các quy tắc, hàm (bao gồm cả macro), khía cạnh và nhà cung cấp được xác định hoặc xuất lại trong một tệp .bzl hoặc .scl nhất định. Đầu ra của quy tắc này là một nguyên mẫu nhị phân ModuleInfo như được xác định trong stardoc_output.proto trong cây nguồn Bazel.

Mục tiêu đầu ra ngầm ẩn

  • name.binaryproto (đầu ra mặc định): Một giao thức nhị phân ModuleInfo.
  • name.textproto (chỉ được tạo nếu được yêu cầu rõ ràng): phiên bản proto văn bản của name.binaryproto.

Cảnh báo: định dạng đầu ra của quy tắc này không đảm bảo tính ổn định. Phương thức này chủ yếu dành cho Stardoc sử dụng nội bộ.

Đối số

Thuộc tính
name

Tên; bắt buộc

Tên riêng cho mục tiêu này.

deps

Danh sách nhãn; mặc định là []

Danh sách các mục tiêu bao bọc các tệp Starlark được load() bằng src. Các mục tiêu này phải theo cách sử dụng thông thường là các mục tiêu bzl_library, nhưng quy tắc starlark_doc_extract không thực thi điều đó và chấp nhận mọi mục tiêu cung cấp các tệp Starlark trong DefaultInfo.

Xin lưu ý rằng các tệp Starlark được bao bọc phải là tệp trong cây nguồn; Bazel không thể load() tạo tệp.

src

Nhãn; bắt buộc

Một tệp Starlark để trích xuất tài liệu.

Xin lưu ý rằng đây phải là một tệp trong cây nguồn; Bazel không thể tạo tệp load().

render_main_repo_name

Boolean; giá trị mặc định là False

Nếu đúng, hãy hiển thị nhãn trong kho lưu trữ chính trong tài liệu đã phát hành bằng một thành phần kho lưu trữ (nói cách khác, //foo:bar.bzl sẽ được phát hành dưới dạng @main_repo_name//foo:bar.bzl).

Tên dùng cho kho lưu trữ chính được lấy từ module(name = ...) trong tệp MODULE.bazel của kho lưu trữ chính (nếu Bzlmod được bật) hoặc từ workspace(name = ...) trong tệp WORKSPACE của kho lưu trữ chính.

Bạn nên đặt thuộc tính này thành False khi tạo tài liệu cho các tệp Starlark chỉ được dùng trong cùng một kho lưu trữ và thành True khi tạo tài liệu cho các tệp Starlark được dùng từ các kho lưu trữ khác.

symbol_names

Danh sách các chuỗi; mặc định là []

Danh sách không bắt buộc gồm các tên đủ điều kiện của các hàm, quy tắc, nhà cung cấp hoặc khía cạnh được xuất (hoặc các cấu trúc mà chúng được lồng trong đó) để trích xuất tài liệu. Ở đây, tên đủ điều kiện có nghĩa là tên mà theo đó một thực thể được cung cấp cho người dùng mô-đun, bao gồm mọi cấu trúc mà thực thể được lồng trong đó để phân vùng không gian tên.

starlark_doc_extract phát tài liệu cho một thực thể nếu và chỉ nếu

  1. mỗi thành phần của tên đủ điều kiện của thực thể đều là công khai (nói cách khác, ký tự đầu tiên của mỗi thành phần của tên đủ điều kiện là chữ cái, không phải "_");
    1. hoặc danh sách symbol_names đang trống (trường hợp mặc định), hoặc
    2. tên đủ điều kiện của thực thể hoặc tên đủ điều kiện của một cấu trúc mà thực thể được lồng trong đó nằm trong danh sách symbol_names.

test_suite

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 nhóm các kiểm thử được coi là "hữu ích" đối với con người. Điều này cho phép các dự án xác định các bộ 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ử tải của dự án" hoặc "tất cả các kiểm thử nhỏ". Lệnh blaze test tuân theo cách sắp xếp 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ả các mục tiêu kiểm thử được bao gồm một cách bắc cầu theo mục tiêu //some/test:suite (chúng ta gọi đây là "mở rộng bộ kiểm thử"), 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 tất cả các 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ử không ổn định trong gói hiện tại.

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

Đối số

Thuộc tính
name

Tên; bắt buộc

Tên riêng cho mục tiêu này.

tags

Danh sách các chuỗi; không thể định cấu hình; mặc định là []

Danh sách các thẻ văn bản, chẳng hạn như "small" hoặc "database" hoặc "-flaky". 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ự "-" đứng trước không được coi là một phần của thẻ, vì vậy thẻ bộ kiểm thử "-small" sẽ khớp với kích thước "small" của một kiểm thử. Tất cả các thẻ khác đều được coi là thẻ tích cực.

Bạn cũng có thể bắt đầu bằng ký tự "+" để làm cho thẻ tích cực rõ ràng hơn. Ký tự này sẽ không được đánh giá như một phần của văn bản trong thẻ. Nó chỉ giúp bạn dễ đọc sự khác biệt giữa giá trị dương và giá trị âm.

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

Từ khoá thẻ manual được xử lý khác với từ khoá ở trên bằng "phần mở rộng bộ kiểm thử" 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 có ký tự đại diện. Tại đó, các mục tiêu test_suite được gắn thẻ "thủ công" sẽ bị lọc (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 có ký tự đại diện nói chung. Xin lưu ý rằng điều này khác biệt rõ ràng so với cách blaze query 'tests(E)' hoạt động, vì các bộ luôn được mở rộng bằng hàm truy vấn tests, bất kể thẻ manual.

Xin lưu ý rằng size của một thử nghiệm được coi là thẻ cho 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 3 quy tắc test_suite: một quy tắc cho tất cả kiểm thử nhỏ, một quy tắc cho tất cả kiểm thử trung bình và một quy tắc bao gồm 2 quy tắc trước đó.

tests

Danh sách nhãn; không thể định cấu hình; mặc định là []

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

Mọi *_test đều được chấp nhận ở đây, bất kể ngôn ngữ. Không chấp nhận *_binary mục tiêu, ngay cả khi mục tiêu đó chạy thử nghiệm. Việc lọc theo tags được chỉ định chỉ được thực hiện cho các 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 test_suite, thì các kiểm thử bên trong những test_suite đó sẽ không được lọc theo 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ì 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 phải tuân theo quy trình lọc tag.