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 để tham chiếu đến quy tắc.

Gán 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.

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à nó tham chiếu (ví dụ: chỉ kiểm thử trên bí danh bị bỏ qua; thay vào đó, tính chất chỉ kiểm thử của quy tắc được tham chiếu sẽ được sử dụng) với một số ngoại lệ nhỏ:

  • Các chương trình 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 mục tiêu duy nhất trong thuộc tính tests.
  • Khi xác định nhóm môi trường, các bí danh cho quy tắc environment không được hỗ trợ. 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

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 tham chiếu đến. Không nhất thiết phải là quy tắc, mà cũng có thể là tệp đầu vào.

config_setting

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

So 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 quy tắc ràng buộc 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 select để biết cách sử dụng quy tắc này và 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ụ

Nội dung sau đây khớp với mọi bản dựng đặt --compilation_mode=opt hoặc -c opt (rõ ràng ở dòng lệnh hoặc ngầm ẩn từ tệp .bazelrc):

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

Nội dung sau đây khớp với 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"
      }
  )
  

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

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

Nội dung sau đây khớp với mọi bản dựng nhắm đến 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 nền tảng đó xác định thêm các giá trị ràng buộ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ả các trường hợp này, cấu hình có thể thay đổi trong bản dựng, 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ờ dòng lệnh cấp cao nhất, config_setting vẫn có thể khớp với một số mục tiêu bản dựng.

Ghi chú

  • Hãy xem 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ợ các 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 này tự động khớp với 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ị (chẳng hạn như --copt=-Da --copt=-Db hoặc cờ Starlark được nhập dưới dạng danh sách), thì 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ự: 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 bản sao: --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 thử kỹ các điều kiện để xác minh chính xác các kỳ vọng.

  • 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 sẽ hỗ trợ kém hơn và không được khuyến khích. Hãy xem nội dung thảo luận tại đây để biết thêm thông tin.
  • 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.
  • Bạn có thể sử dụng values, define_valuesconstraint_values theo bất kỳ tổ hợp nào trong cùng một config_setting, nhưng ít nhất phải đặt một trong số này cho bất kỳ config_setting nào.

Đố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. (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 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à 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ể khớp với một nền tảng nhiều 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 của nó (--define KEY=VAL) có nghĩa là KEY=VAL là một giá trị từ góc độ 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 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 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ể được 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 dành cho cờ bản dựng do người dùng xác định.

Đây là một thuộc tính khác 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 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 mục tiêu đó trong câu lệnh select. Từ điển này được coi là "khớp" với 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 mục tiêu.

Để thuận tiện, các giá trị cấu hình được chỉ định dưới dạng cờ bản dựng (không có "--" đứng 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" 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, 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 cờ rõ ràng 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 gần đây nhất mới đượ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ì một kết quả trùng 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

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 tập hợp các mục tiêu. Sau đó, bạn có thể tham chiếu các giá trị 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. Cách thứ hai là không hợp lý 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, vì vậy, hệ thống có thể không tạo 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 filegroup bao gồm hai 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 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 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 các mục tiêu là thành viên của nhóm tệp.

Thông thường, bạn sẽ sử 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 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 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 đã 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 đó.

genquery

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 trong ngôn ngữ truy vấn Blaze 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 tập hợp đó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 thi được nếu strict không được chỉ định hoặc là true (nếu strict là false, thì 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 điều 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à các truy vấn chứa thông số kỹ thuật của mục tiêu ký tự đại diện (ví dụ: //pkg:* hoặc //pkg:all) không được phép ở đây. Lý do cho việc này có hai khía cạnh: 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 phạm vi đóng vi mô của truy vấn ảnh hưởng đến kết quả 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ụ: không cho phép deps=["//a/..."]).

Đầu ra của genquery được sắp xếp bằng --order_output=full để thực thi đầu ra có tính quyế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 tập hợp đó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 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 ở đâ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 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ố tuỳ chọn truy vấn không được phép ở đâ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 của 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 phạm vi đóng chuyển đổi của các mục tiêu này.
strict

Boolean; optional; default is True

Nếu đúng, các mục tiêu có truy vấn thoát khỏi phạm vi đóng vi mô 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 mọi đường dẫn truy vấn dẫn ra ngoài phạm vi, đồng thời hoàn tất phần còn lại của truy vấn.

genrule

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 cách sử dụng lệnh Bash do người dùng xác định.

Genrules 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 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 nề đã được thực hiện cho bạn.

Không sử dụng genrule để chạy kiểm thử. Có các trường hợp miễn trừ đặc biệt đối với các chương trình 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à biến môi trường. Các chương trình kiểm thử 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 genrules được thực thi trong quá trình xây dựng và trên cấu trúc máy chủ (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ề việc biên dịch chéo.

Mặc dù genrules 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 khi tạo bản dựng, để triển khai hoặc kiểm thử. 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. Rõ ràng là mã được tạo không thể chạy trên CPU dùng để tạo mã đó, nhưng chính 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 máy chủ để 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 đó. Công cụ này cung cấp các tuỳ chọn để định cấu hình từng tệp 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 genrules, hệ thống xây dựng đảm bảo rằng các phần phụ thuộc được tạo một cách thích 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à đầ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à lệnh genrule có thể truyền đến các công cụ tương ứng.

Genrule cố ý 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 genrule không thể tự động hoá ở mức này. Genrules hoạt động hoàn toàn ở cấp tệp và runfiles.

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

Biên dịch máy chủ lưu trữ-máy chủ lưu trữ: trong một số trường hợp, hệ thống xây dựng cần chạy genrules để đầu ra cũng có thể được thực thi trong quá trình xây dựng. Ví dụ: nếu một genrule tạo một số 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 đầu ra cho cấu hình máy chủ, 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 cần làm: tạo srcsouts của genrule đầu tiên cho cấu hình máy chủ 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 JDK hoặc bộ trình 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. Hãy xem biến"Make" để biết chi tiết.

Môi trường genrule

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

Công cụ bản dựng 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 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 đến lệnh của 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à con của chính lệnh đó, mặc dù điều này hiện 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 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 không thành công.

Lời khuyên chung

  • Hãy đảm bảo rằng các công cụ do genrule chạy là có tính quyết định và kín. Các hàm này không được ghi dấu thời gian vào đầu ra và 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 có đường dẫn tuyệt đối. Việc không tuân thủ 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 genrule mà bạn nghĩ là sẽ tạo lại) và làm giảm hiệu suất của bộ nhớ đệm.
  • Hãy sử dụng $(location) rộng rãi cho các đầu ra, công cụ và nguồn. Do việc phân tách các tệp đầu ra cho nhiều cấu hình, genrules không thể dựa vào các đường dẫn tuyệt đối và/hoặc được mã hoá cứng.
  • Hãy viết một macro Starlark phổ biến trong trường hợp các genrules giống nhau hoặc rất giống nhau được sử dụng ở nhiều vị trí. Nếu genrule phức tạp, hãy cân nhắc triển khai genrule đó 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ử.
  • Hãy đảm bảo rằng mã thoát cho biết chính xác trạng thái thành công hoặc không thành công 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ó âm thanh. 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 đườ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 là phương pháp khác: tham chiếu đầ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ể gây phiền toái 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 không nhận bất kỳ dữ liệu đầu vào nào. "Tệp nhị phân" do lệnh này 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 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ì các lệnh $(location) rõ ràng cũng sẽ hoạt động; ví dụ này sử dụng lệnh sau để 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 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

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 các điều kiện tiên quyết này được tạo trước khi chạy lệnh genrule; các điều kiện tiên quyết này được tạo bằng cách sử dụng cùng một cấu hình với yêu cầu bản dựng ban đầu. Tên của các tệp của các đ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 sử dụng $<, miễn là đó là mục nhập duy nhất trong srcs.

outs

List of filenames; required; nonconfigurable

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

Các 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 bạn đặt cờ executable, 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í này có trong cmd bằng cách sử dụng các biến "Tạo" dành riêng cho genrule ($@, $(OUTS), $(@D) hoặc $(RULEDIR)) hoặc sử dụng tính năng thay thế $(location).

cmd

String; optional

Lệnh để chạy. Chịu sự thay thế của $(location) biến"Make".
  1. Trước tiên, hệ thống sẽ áp dụng phương thức thay thế $(location) , thay thế tất cả các lần xuất hiện $(location label)$(locations label) (và các cấu trúc tương tự sử dụng các biến liên quan execpath, execpaths, rootpathrootpaths).
  2. Tiếp theo, các biến"Make" 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 máy chủ lưu trữ, vì vậy, 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 cách sử dụng shell Bash. Nếu mã thoát của lệnh này khác 0, thì lệnh đó đượ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 áp dụng được.

Nếu chiề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

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 Hàng loạt để 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 tương tự như thuộc tính cmd, với các đ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 – xoá dấu ngoặc kép đầu tiên và cuối cùng rồi thực thi mọi nội dung khác như hiện 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ì 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 chạy 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 gặp 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 genrule.

  • Set-ExecutionPolicy -Scope CurrentUser RemoteSigned – cho phép chạy 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 nếu một 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 bộ 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ông cụ cho 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 tuân theo các giới hạn giống như các phần phụ thuộc trong tools. Cụ thể, các phần phụ thuộc này 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ác trường hợp sử dụng tools để sử dụng ngữ nghĩa exec_tools. Người dùng nên ưu tiên exec_tools hơn tools nếu điều này không gây ra vấn đề nào. Sau khi di chuyển chức năng xong, chúng ta có thể đổi tên exec_tools thành tools. Bạn sẽ nhận được cảnh báo ngừng sử dụng và hướng dẫn di chuyển trước khi việc này xảy ra.

executable

Boolean; optional; nonconfigurable; default is False

Khai báo đầu ra là 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, genrule phải tạo ra đúng 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 phần phụ thuộc dữ liệu cho tệp thực thi được tạo.

local

Boolean; optional; default is False

Nếu bạn đặt thành True, tuỳ chọn này sẽ buộc genrule này chạy bằng chiến lược "local" (cục bộ), tức là không thực thi từ xa, không tạo hộp cát, không có worker ổn đị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.

Thông báo tiến trình sẽ được in khi thực thi bước xây dựng này. Theo mặc định, thông báo là "Tạo đầu ra" (hoặc một thông báo tương tự) nhưng bạn có thể cung cấp một thông báo cụ thể hơn. 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ó in các thông báo tiến trình đó 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 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

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 các điều kiện tiên quyết này được tạo trước khi chạy lệnh genrule; các điều kiện tiên quyết này được tạo bằng cách sử dụng cấu hình máy chủ, 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 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, chứ không phải trong srcs, để đảm bảo chúng được tạo ở đú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 bài 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 kiểm thử", "các kiểm thử cường độ cao 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 lệnh gọi như blaze test //some/test:suite, trước tiên, Blaze liệt kê tất cả cá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 bộ kiểm thử"), sau đó Blaze 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"],
)

Bộ kiểm thử chạy một tập hợp các chương trình 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 không bị lỗi.

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

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 kiểm thử. Tất cả thẻ khác được coi là thẻ dương.

Nếu muốn, để làm cho thẻ dương tính rõ ràng hơn, 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 của văn bản thẻ. Việc này chỉ giúp phân biệt giá trị dương và âm dễ đọc hơn.

Chỉ những quy tắc kiểm thử khớp với tất 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à bạn sẽ bỏ qua 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ử bị lọc ra; 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 hợp lệ (ví dụ: không bị các quy tắc ràng buộc về chế độ hiển thị chặn).

Từ khoá thẻ manual được xử lý theo cách khác với trên bằng lệnh "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 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 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 đại diện nói chung. Xin lưu ý rằng điều này khác hẳn với cách hoạt động 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.

Xin lưu ý rằng size của một kiểm thử đượ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 ba 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 hai quy tắc trước đó.

tests

List of labels; optional; nonconfigurable

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

Mọi *_test đều được chấp nhận ở đây, độc lập với ngôn ngữ. Tuy nhiên, không chấp nhận mục tiêu *_binary, ngay cả khi mục tiêu đó chạy thử nghiệm. Việc lọc theo tags đã 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 các test_suite đó sẽ không được test_suite này lọc (các kiểm thử đó được coi là đã được lọc).

Nếu thuộc tính tests không được chỉ định hoặc trống, thì quy tắc sẽ mặc định bao gồm tất 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.