Quy tắc chung

Báo cáo vấn đề 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 mà quy tắc có thể được dùng.

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

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

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

  • Quá trình kiểm thử sẽ không chạy nếu email đại diện 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 của quy tắc đó.
  • Khi xác định nhóm môi trường, bí danh cho quy tắc environment không được hỗ trợ. Các thành phầ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 duy nhất cho mục tiêu này.

actual

Nhãn; bắt buộc

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

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 với một 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 của nền tảng) nhằm mục đích kích hoạt các thuộc tính có thể định cấu hình. Xem phần chọn để biết cách sử dụng quy tắc này và Các thuộc tính có thể định cấu hình để biết thông tin tổng quan về tính năng chung.

Ví dụ

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

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

Mã 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"
      }
  )
  

Phần 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 (thể hiện rõ ràng tại dòng lệnh hoặc ngầm ẩn trong các tệp .bazelrc):

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

Đoạn mã sau 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ử tồn tại một constraint_value có nhãn //example:glibc_2_25. Xin lưu ý rằng một nền tảng vẫn trùng khớp nếu nền tảng đó xác định thêm các giá trị ràng buộc khác ngoài 2 giá trị này.

  config_setting(
      name = "64bit_glibc_2_25",
      constraint_values = [
          "@platforms//cpu:x86_64",
          "//example:glibc_2_25",
      ]
  )
  
Trong tất cả những trường hợp này, cấu hình đều có thể thay đổi trong bản dựng, chẳng hạn như khi một 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 của nền tảng đó. Tức là ngay cả khi config_setting không khớp với cờ hiệu dòng lệnh cấp cao nhất, mục tiêu đó vẫn có thể khớp với một số mục tiêu của bản dựng.

Ghi chú

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

    values = { "myflag": "a,b" } hoạt động theo cách tương tự: 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 ["a,b"] trong khi --copt=a --copt=b tạo ["a", "b"] (vì vậy values = { "copt": "a,b" } khớp với phiên bản trước nhưng không khớp với phiên bản sau). Tuy nhiên, --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"]. Hãy kiểm tra các định nghĩa về cờ và kiểm tra kỹ các điều kiện của bạn để xác minh các 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 lập mô hình 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 tính năng này cung cấp dịch vụ hỗ trợ yếu hơn và không nên dùng. 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 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 config_setting nhưng phải đặt ít nhất một mục cho config_setting cho trước.

Đối số

Thuộc tính
name

Tên; bắt buộc

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

constraint_values

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

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 khác mà nền tảng đã bỏ qua đề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 hai config_setting cùng 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 thuộc tính còn lại hay không. Nói cách khác, một config_setting không thể so khớp với một nền tảng mạnh hơn một nền tảng khác.

define_values

Từ điển: Chuỗi -> Chuỗi; không thể định cấu hình; mặc định là {}

Tương tự 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) 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 có tác dụng vì cùng một khoá (define) xuất hiện hai lần trong từ điển. Thuộc tính này sẽ giải quyết vấn đề đó:

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

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

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

flag_values

Từ điển: label -> Chuỗi; không thể định cấu hình; giá trị mặc định là {}

Tương tự 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 chuỗi tuỳ ý.

values

Từ điển: Chuỗi -> Chuỗi; không thể định cấu hình; mặc định là {}

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

Quy tắc này kế thừa cấu hình của mục tiêu đã định cấu hình tham chiếu đến mục tiêu đó trong câu lệnh select. Lệnh gọi này được coi là "khớp" với lệnh gọi Bazel nếu 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 đó đối với mọi mục nhập trong từ điển. 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, các giá trị cấu hình được chỉ định là 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 một 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 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 chúng.

Nếu cờ không được đặt 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ỉ có trường hợp gần nhất đượ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ì kết quả trùng khớp sẽ xảy ra nếu bất kỳ chế độ cài đặt nào trong số đó trùng khớp.

nhóm tệp

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 tập hợp 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. Tệp sau không hợp lệ vì hệ thống xây dựng không có đầy đủ kiến thức về tất cả tệp bên dưới thư mục, vì vậy, hệ thống có thể không tạo lại được khi các tệp này thay đổi. Khi được kết hợp với glob, filegroup có thể đảm bảo rằng hệ thống xây dựng đã biết rõ tất cả các tệp.

Ví dụ

Để tạo một filegroup bao gồm hai tệp nguồn, hãy làm

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

Bạn cũng có thể sử dụng glob để thu gọn 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 filegroup cùng với 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 duy nhất 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.

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

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ên trong thuộc tính data sẽ được thêm vào runfiles của quy tắc filegroup này. Khi filegroup được tham chiếu trong thuộc tính data của một quy tắc khác, runfiles của nó sẽ được thêm vào runfiles của quy tắc phụ thuộc. Hãy xem mục phần phụ thuộc của 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

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

Nhóm đầu ra để thu thập cấu phần phần mềm từ các nguồn. Nếu thuộc tính này được chỉ định, 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 gồm 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 đó.

truy vấn tạo

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 bằng Ngôn ngữ truy vấn tăng dần và kết xuất kết quả vào một tệp.

Để đảm bảo bản dựng luôn nhất quán, truy vấn chỉ được phép truy cập vào đó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 true (nếu strict là false), 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á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à những truy vấn có chứa thông số kỹ thuật đích ký tự đại diện (ví dụ: //pkg:* hoặc //pkg:all) không được phép ở đây. Có 2 lý do dẫn đến điều này: thứ nhất, vì genquery phải chỉ định một phạm vi để ngăn các mục tiêu nằm ngoài đường đóng bắc cầu của truy vấn nhằm tác động đến kết quả của truy vấn đó; 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 cho phép).

Kết quả của truy vấn tạo được sắp xếp theo từ điển để thực thi đầu ra tất đị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 quá trình đó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

Tên; bắt buộc

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

compressed_output

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

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

Chuỗi; bắt buộc

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

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

Các tuỳ chọn được chuyển đến công cụ truy vấn. Các đối tượng này tương ứng với các tuỳ chọn dòng lệnh có thể được truyền đến bazel query. Bạn không được phép sử dụng một số lựa chọn cho truy vấn ở đâ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

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 nằm ngoài phạm vi đó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, các mục tiêu có truy vấn thoát khỏi trạng thái đóng bắc cầu của phạm vi sẽ không thể tạo. Nếu đặt là false, Bazel sẽ in một cảnh báo và bỏ qua bất kỳ đường dẫn truy vấn nào đưa nó ra ngoài phạm vi, đồng thời hoàn thành phần còn lại của truy vấn.

quy tắc tạo sinh

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.

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

Lưu ý rằng quy tắc gen 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 khảo 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 bị ngắt quãng 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 sinh để chạy kiểm thử. Có những sự khác biệt đặc biệt đối với các kiểm thử và kết quả kiểm thử, bao gồm cả các chính sách lưu vào bộ nhớ đệm và các biến môi trường. Thường thì bạn cần chạy chương trình kiểm thử sau khi quá trình xây 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 thực thi (hai cấu trúc 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ể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ề quá 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 dữ liệu đầu ra của chúng thường được 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 vi điều khiển. Mã được tạo rõ ràng không thể chạy trên CPU dùng để tạo mã đó, nhưng bản thân trình biên dịch C (nếu được biên dịch từ nguồn) phải làm 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 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ẽ chạy trên đó. Lớp này cung cấp các tuỳ chọn để định cấu hình từng yếu tố trong số này và 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 phù hợp: 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à dành 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.

Có thể chủ ý rằng quy tắc gen không xác định thuộc tính deps: các quy tắc tích hợp sẵn 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 quy tắc gen không thể tự động hoá ở mức độ này. Genrules chỉ hoạt động ở cấp tệp và runfile.

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 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 quy tắc gen tạo một trình biên dịch tuỳ chỉnh nào đó sau đó được một quy tắc gen khác sử dụng, thì quy tắc đầu tiên phải tạo đầu ra cho cấu hình exec này, vì đó là nơi trình biên dịch sẽ chạy trong quy tắc gen khác. Trong trường hợp này, hệ thống xây dựng sẽ tự động thực hiện hoạt động đúng cách: hệ thống sẽ tạo srcsouts của quy tắc gen đầu tiên cho cấu hình thực thi thay vì cấu hình mục tiêu. Xem hướng dẫn sử dụng để biết thêm thông tin.

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

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

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

Công cụ xây dựng này 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 chính như PATH, PWD, TMPDIR và một vài 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 chuyển qua lệnh của quy tắc gen. Tuy nhiên, Bazel (nhưng không phải Blaze) chuyển qua giá trị của biến môi trường PATH của người dùng. Mọi thay đổi đối với giá trị của PATH sẽ khiến Bazel thực thi lại lệnh trên bản dựng tiếp theo.

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

Lời khuyên chung

  • Đảm bảo rằng các công cụ chạy theo quy tắc tạo sinh có tính tất định và mang tính khép kín. Các lớp này không nên ghi dấu thời gian vào dữ liệu đầu ra và nên sử dụng thứ tự ổn định cho các tập hợp và bản đồ, cũng như chỉ viết các đường dẫn tệp tương đối cho kết quả đầu ra, chứ không phải là đườ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 một quy tắc chung mà bạn nghĩ là sẽ làm) 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 dữ liệu đầu ra, công cụ và nguồn. Do các tệp đầu ra được phân tách cho nhiều cấu hình, nên quy tắc gen không thể dựa vào các đường dẫn được mã hoá cứng và/hoặc đường dẫn tuyệt đối.
  • 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 quy tắc tạo sinh 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 thử.
  • Hãy đảm bảo rằng mã thoát cho biết chính xác quy tắc gen được tạo thành công hay không thành công.
  • Không viết thư cung cấp thông tin cho 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ở nên gây nhiễu; quy tắc tạo thành công nên im lặng. Mặt khác, một quy tắc tạo không thành công sẽ phát ra các 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 đườ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ác thư mục là không phù hợp.
  • Khi tham chiếu quy tắc gen trong các quy tắc khác, bạn có thể dùng nhãn của quy tắc gen hoặc nhãn của từng tệp đầu ra. Đôi khi, phương pháp này sẽ dễ đọc hơn, nhưng cũng có khi cách khác: tham chiếu các kết quả theo tên trong srcs của quy tắc tiêu thụ sẽ tránh được việc vô tình chọn các kết quả khác của quy tắc gen, nhưng có thể trở nên tẻ nhạt nếu quy tắc gen tạo ra nhiều đầu ra.

Ví dụ

Ví dụ này tạo 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. "Tệp 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 quy tắc gen.

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

Ví dụ sau đây cho thấy cách sử dụng một filegroup và kết quả của một genrule khác. Hãy lưu ý rằng bạn cũng có thể dùng $(SRCS) thay vì lệnh $(location) rõ ràng. Ví dụ này dùng lệnh sau nhằm 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 duy nhất cho mục tiêu này.


Bạn có thể tham chiếu đến quy tắc này theo tên trong mục srcs hoặc deps của các quy tắc BUILD khác. Nếu quy tắc này tạo tệp nguồn, 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 dữ liệu đầu vào cho quy tắc này, chẳng hạn như 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. 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 những điều kiện tiên quyết này được tạo trước khi chạy lệnh genRules. Các điều kiện này được tạo bằ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 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 //x:y mục tiêu srcs riêng lẻ bằng $(location //x:y) hoặc sử dụng $< 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 qua ranh giới của gói. Tên tệp đầu ra được diễn giải 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 genrules sẽ tạo từng tệp đầu ra tại một vị trí được xác định trước. Vị trí này có sẵn trong cmd bằng cách sử dụng các biến "Make" cụ thể theo quy tắc gen ($@, $(OUTS), $(@D) hoặc $(RULEDIR)) hoặc sử dụng phép thay thế $(location).

cmd

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

Lệnh cần chạy. Phải tuân theo việc thay thế $(location) biến"Tạo".
  1. Phương thức thay thế $(location) đầu tiên được áp dụng, thay thế tất cả các lần xuất hiện của $(location label)$(locations label) (và các công trình tương tự sử dụng các biến liên quan execpath, execpaths, rootpathrootpaths).
  2. Tiếp theo, các biến"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. 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 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 được thực thi bằng cách sử dụng shell Bash. Nếu mã thoát của lệnh đó khác 0, lệnh được coi là không thành công.
Đây là phương án dự phòng cho cmd_bash, cmd_pscmd_bat, nếu không có phương án nào phù hợp.

Nếu độ dài dòng lệnh vượt quá giới hạn của nền tảng (64K trên Linux/macOS, 8K trên Windows), thì genrules sẽ ghi lệnh vào một tập lệnh và thực thi tập lệnh đó để giải quyết. Lệnh 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à ""

Chạy lệnh Bash.

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

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, 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 chạy bằng cmd.exe /c với các đối số mặc định sau:
    • /S – bỏ dấu ngoặc kép đầu và cuối, đồng thời thực thi mọi nội dung còn lại.
    • /E:ON – bật tập lệnh mở rộng.
    • /V:ON – bật tính năng mở rộng biến được trì hoãn
    • /D – bỏ qua các mục nhập đăng ký AutoRun.
  • Sau khi thay thế $(location)biến"Make", các đường dẫn này sẽ được mở rộng thành đường dẫn 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, 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 chạy bằng powershell.exe /c.

Để Powershell dễ sử dụng hơn và ít gặp 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 genrules.

  • Set-ExecutionPolicy -Scope CurrentUser RemoteSigned – cho phép chạy các tập lệnh chưa ký.
  • $errorActionPreference='Stop' – Trong trường hợp có nhiều lệnh được phân tách bằng ;, thao tác sẽ thoát ngay lập tức nếu Powershell CmdLet không thành công, nhưng thao tác này KHÔNG hoạt động 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; giá trị 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, thì kết quả đầu ra là một tệp thực thi và có thể chạy bằng lệnh run. Trong trường hợp này, quy tắc tạo sinh phải tạo ra chính xác một đầu ra. Nếu bạn đặt thuộc tính này, run sẽ thử thực thi tệp bất kể nội dung của tệp.

Không hỗ trợ khai báo 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 chính sách này thành True, thì tuỳ chọn này sẽ buộc genrule này chạy bằng chiến lược "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" dưới dạng thẻ (tags=["local"]).

message

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

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 tạo bản dựng này. Theo mặc định, thông báo là "Đang tạo đầu ra" (hoặc nội dung nào đó không quá rõ ràng) nhưng bạn có thể cung cấp một thông báo cụ thể hơn. Hãy 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 thông báo tiến trình đó có được in 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; giá trị 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 những đ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 này được tạo bằng cấu hình exec, vì những công cụ này được thực thi trong quá trình tạo bản dựng. Bạn có thể lấy đường dẫn của một tools đích //x:y riêng lẻ bằng cách sử dụng $(location //x:y).

Mọi *_binary hoặc công cụ được 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 theo đúng cấu hình.

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à trình cung cấp được xác định hoặc xuất lại trong tệp .bzl hoặc .scl nhất định. Đầu ra của quy tắc này là một proto nhị phân ModuleInfo như được xác định trong stardoc_output.proto trong cây nguồn Bazel.

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

  • name.binaryproto (đầu ra mặc định): Một proto 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 sẽ ổn định. API 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 duy nhất 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 gói các tệp Starlark được load() tạo bởi src. Trong cách sử dụng bình thường, các mục tiêu này phải là mục tiêu bzl_library. Tuy nhiên, quy tắc starlark_doc_extract không thực thi việc đó và chấp nhận mọi mục tiêu cung cấp tệp Starlark trong DefaultInfo của mình.

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

src

Nhãn; bắt buộc

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

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

render_main_repo_name

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

Nếu đúng, hãy kết xuất nhãn trong kho lưu trữ chính ở tài liệu được tạo ra với một thành phần kho lưu trữ (nói cách khác, //foo:bar.bzl sẽ được kích hoạt dưới dạng @main_repo_name//foo:bar.bzl).

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

Bạn phải đặt thuộc tính này thành False khi tạo tài liệu cho các tệp Starlark (chỉ 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 dùng trong các kho lưu trữ khác.

symbol_names

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

Một 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 đã xuất (hoặc cấu trúc chứa các hàm đó được lồng vào nhau) để trích xuất tài liệu. Ở đây, tên đủ điều kiện có nghĩa là tên mà trong đó một thực thể được cung cấp cho người dùng của mô-đun, bao gồm mọi cấu trúc trong đó thực thể được lồng để tạo không gian tên.

starlark_doc_extract cung cấp tài liệu cho một thực thể khi và chỉ khi

  1. mỗi thành phần trong tên đủ điều kiện của thực thể đều 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. danh sách symbol_names trống (đây là 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à trong đó thực thể được lồng sẽ 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 tập hợp chương trình kiểm thử được xem 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 tập hợp kiểm thử, chẳng hạn như "các chương trình kiểm thử bạn phải chạy trước khi kiểm thử", "kiểm thử nghiêm ngặt của dự án" hoặc "tất cả các chương trình kiểm thử nhỏ". Lệnh blaze test tuân theo kiểu tổ chức này: Đối với lệnh gọi như blaze test //some/test:suite, trước tiên, Blaze sẽ liệt kê tất cả mục tiêu kiểm thử được mục tiêu //some/test:suite đưa vào một cách bắc cầu (chúng tôi gọi đây là "mở rộng test_suite"), sau đó Blaze sẽ tạo và kiểm thử các mục tiêu đó.

Ví dụ

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

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

Một bộ kiểm thử chạy một tập hợp các chương trình kiểm thử đã 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 mà không bị gián đoạn.

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

Đối số

Thuộc tính
name

Tên; bắt buộc

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

tags

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

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.

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

Nếu muốn, để làm cho thẻ khẳng đị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á trong văn bản của thẻ. Điều này chỉ đơn thuần làm cho sự khác biệt tích cực và tiêu cực dễ đọc hơn.

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

Từ khoá thẻ manual được xử lý theo cách khác với kiểu ở trên. Tính năng "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 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ẽ được lọc ra (và do đó không được mở rộng). Hành vi này nhất quán với cách blaze buildblaze test xử lý các mẫu đích ký tự đại diện nói chung. Xin lưu ý rằng điều này khác biệt rõ ràng với cách hoạt động của blaze query 'tests(E)', vì các bộ ứng dụng luôn được mở rộng bằng hàm truy vấn tests, bất kể thẻ manual là gì.

Lưu ý size của kiểm thử được coi là một thẻ cho mục đích lọc.

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

tests

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

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, 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 chạy kiểm thử. Việc lọc theo tags đã chỉ định chỉ được thực hiện 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 hoạt động kiểm thử bên trong các hoạt động đó sẽ không được test_suite này lọc (các hoạt động kiểm thử này được coi là đã được lọc).

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