Quy tắc chung

Báo cáo sự cố Xem nguồn Hằng đêm · 7,3 · 7.2 · 7.1 · 7,0 · 6,5

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.

Tình trạng chồng phổ (aliasing) chỉ hoạt động đối với sản phẩm "thông thường" mục tiêu. Cụ thể, package_grouptest_suite không thể đặt bí danh.

Việc tạo bí danh có thể giúp ích trong các kho lưu trữ lớn, trong đó việc đổi tên mục tiêu sẽ yêu cầu thực hiện thay đổi thành nhiều tệp. Bạn cũng có thể sử dụng quy tắc bí danh để lưu trữ chọn lệnh gọi hàm nếu bạn 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. Trong tất cả các khía cạnh khác, nó 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; quy tắc 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 bí danh chạy kiểm thử được tham chiếu, hãy sử dụng test_suite quy tắc có một mục tiêu duy nhất trong tests .
  • 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 không được hỗ trợ trong dòng lệnh --target_environment lựa chọn.

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. Không cần phải là quy tắc, nó cũng có thể là dữ liệu đầ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)

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 của nền tảng) đối với mục đích của việc kích hoạt các thuộc tính có thể định cấu hình. Xem mục chọn cho cách áp dụng quy tắc này và Thuộc tính có thể định cấu hình để xem thông tin tổng quan về tính năng chung.

Ví dụ

Mã 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 mục tiêu đế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"
      }
  )
  

Các mã sau đây khớp với bất kỳ bản dựng nào đặt cờ do người dùng xác định --//custom_flags:foo=1 (thể hiện rõ ràng tại dòng lệnh hoặc ngầm ẩn từ tệp .bazelrc):

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

Nội dung sau đây phù hợ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ả định tồn tại của constraint_value có nhãn //example:glibc_2_25. Xin lưu ý rằng nền tảng vẫn so khớp nếu nền tảng đó xác định các thông số bổ sung các giá trị ràng buộc khác ngoài hai giới hạn 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, ví dụ: 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. Đ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, nhưng vẫn có thể khớp một số mục tiêu xây dựng.

Ghi chú

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

    values = { "myflag": "a,b" } cũng 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ờ. Ví dụ: --copt không hỗ trợ nhiều giá trị trong cùng một thực thể: --copt=a,b tạo ["a,b"] trong khi --copt=a --copt=b tạo ["a", "b"] (do đó values = { "copt": "a,b" } phù hợp với cái trước nhưng không khớp với cái 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 các điều kiện cụ thể để 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 miền này cung cấp yếu hơn và không được khuyến khích. 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.
  • values! define_valuesconstraint_values có thể được sử dụng kết hợp bất kỳ trong cùng config_setting nhưng ít nhất một mục phải được đặt cho bất kỳ 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 phải là 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. Xem Thuộc tính bản dựng có thể định cấu hình để biết thông tin chi tiết.

Nếu hai config_setting trùng khớp trong cùng một select và một có tất cả những cờ giống nhau và constraint_settingnhư những cờ khác cộng thêm các cờ khác, mục có nhiều chế độ cài đặt hơn được chọn. Đây gọi là "chuyên môn". Ví dụ: một config_setting khớp với x86Linux chuyên config_setting khớp với x86.

Nếu 2 config_setting trùng khớp và cả 2 đều có constraint_value không có trong dữ liệu khác, thì đây là lỗi.

define_values

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

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 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 có 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 vẫn khác biệt.

flag_values

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

Giống như values nhưng 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: Chuỗi -> String; không thể định cấu hình; giá trị 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 lớp đó trong câu lệnh select. Điều này được coi là "khớp" một lệnh gọi Bazel nếu, đối với mọi mục nhập trong từ điển, cấu hình khớp với giá trị dự kiến của mục nhập. Ví dụ: values = {"compilation_mode": "opt"} khớp với lệnh gọi bazel build --compilation_mode=opt ...bazel build -c opt ... trên các quy tắc được định cấu hình mục tiêu.

Để thuận tiện, các giá trị cấu hình được chỉ định là cờ bản dựng (không có "--" trước đó). Nhưng hãy lưu ý rằng hai tính năng này không giống nhau. Chiến dịch này là do các mục tiêu có thể được xây dựng trong nhiều cấu hình trong cùng một bản dựng. Ví dụ: "cpu" của cấu hình thực thi khớp với giá trị của --host_cpu, chứ không phải --cpu. Vì vậy, các trường hợp 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 nhưng khác 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ể đặ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ố đó 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 để thu thập kết quả của một tập hợp các mục tiêu trong một .

filegroup không thay thế cho việc liệt kê mục tiêu trên dòng lệnh hoặc trong thuộc tính của một quy tắc khác, bởi vì mục tiêu có nhiều thuộc tính khác với và không được thu thập theo cách tương tự. Tuy nhiên, công cụ này vẫn hữu ích trong một vài trường hợp, ví dụ: trong thuộc tính srcs của một quy tắc gen, hoặc thuộc tính data của quy tắc *_nhị phân.

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ả các tệp bên dưới thư mục này, nên có thể tệp sẽ 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 tất cả các tệp được được hệ thống xây dựng biết rõ.

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",
        "//a/library:target",
        "//a/binary:target",
    ],
)

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; giá trị 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ì chúng ta 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; giá trị 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 trong số filegroup quy tắc này. Khi filegroup được tham chiếu trong thuộc tính data của một quy tắc khác, runfiles của nó sẽ được thêm vào runfiles của quy tắc phụ thuộc. Xem các phần phụ thuộc dữ liệutài liệu chung về data để biết thêm thông tin về cách phụ thuộc và sử dụng tệp dữ liệu.

output_group

String; 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 là 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à 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 đó 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 trong Ngôn ngữ truy vấn Bazel và kết xuất kết quả vào một tệp.

Để giữ công trình xây dựng nhất quán, truy vấn chỉ được phép truy cập đóng bắc cầu của các mục tiêu được chỉ định trong scope . Các truy vấn vi phạm quy tắc này sẽ không thực thi được nếu strict là không xác định hoặc true (nếu strict là false, các mục tiêu nằm ngoài phạm vi sẽ bị bỏ qua kèm theo cảnh báo). Chiến lược phát hành đĩa đơn 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.

Sự khác biệt duy nhất giữa các truy vấn được phép ở đây và trong lệnh là những truy vấn 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ó hai lý do dẫn đến điều này, thứ nhất là vì genquery đã để chỉ định phạm vi ngăn chặn các mục tiêu nằm ngoài hệ thống đóng bắc cầu của truy vấn để tác động đến kết quả của truy vấn đó; và thứ hai là vì BUILD tệp không hỗ trợ phần phụ thuộc ký tự đại diện (ví dụ: deps=["//a/..."] là không được phép).

Đầu ra 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 viết danh sách các nhãn trong đóng cầu nối của đích đượ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ể dùng chế độ cài đặt này để tránh mức tăng đột biến trong mức sử dụng bộ nhớ của Bazel khi kết quả truy vấn dự kiến sẽ lớn. Bazel sản xuất đã 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, vì vậy, việc đặt giá trị này thành True có thể không làm giảm dữ liệu được giữ lại vùng nhớ khối xếp. 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, mà có thể tốn nhiều bộ nhớ.
expression

String; 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, 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

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

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

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 bắc cầu việc đóng 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ể bản dựng. 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 dẫn nó ra ngoài trong khi hoàn tất 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 các tệp C++, hãy tiếp tục theo các quy tắc cc_* hiện tại, vì tất cả các công việc khó khăn đã đượ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 việc này giúp không lặp lại 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 thay thế.

Giống như mọi hành động khác, hành động do genrules tạo ra không nên giả định bất cứ điều gì về thư mục đang làm việc; tất cả đều đảm bảo của Bazel là thông tin đầu vào mà họ đã khai báo sẽ có sẵn tại đường dẫn mà $(location) trả về cho nhãn của chúng. Ví dụ: nếu hành động được chạy trong một hộp cát hoặc từ xa, việc triển khai hộp cát hoặc thực thi từ xa sẽ xác định thư mục đang làm việc. Nếu chạy trực tiếp (sử dụng chiến lược standalone), chiến lược thư mục sẽ là gốc thực thi, tức là kết quả của bazel info execution_root.

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 cho các bài kiểm thử và kiểm thử kết quả, 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 chương trình kiểm thử sau khi quá trình tạo 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 bản dựng và kiến trúc exec (hai có thể khác nhau). Nếu bạn cần mục đích chung quy tắc thử nghiệm, 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ề 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 tệp nguồn và tạo mã chạy trên vi điều khiển. Mã được tạo một cách rõ ràng không thể chạy trên CPU dùng để tạo ứng dụng đó, nhưng trình biên dịch C (nếu được biên dịch từ nguồn) phải làm.

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 là phải chạy. 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 riêng các tệp tương ứng vào các thư mục riêng biệt để tránh xung đột.

Đối với 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 mục tiêu, tools được tạo cho cấu hình exec và đầu ra được coi là dành cho cấu hình target. API này cũng cung cấp "Nhãn hiệu" các biến mà các lệnh genRule có thể truyền đến các công cụ tương ứng.

Có chủ ý rằng quy tắc gen không xác định thuộc tính deps nào: 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 chuyể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ể tự động hoá quy tắc genrules. Hoạt động tạo quy tắc chỉ ở 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 sao cho đầu ra cũng có thể được thực thi trong quá trình tạo. Ví dụ: nếu một genrules tạo một số trình biên dịch tuỳ chỉnh sau đó được một quy tắc sinh khác sử dụng, quy tắc đầu tiên phải tạo đầu ra cho quy tắc cấu hình exec, 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 tạo srcsouts của quy tắc tạo sinh đầu tiên cho cấu hình thực thi thay vì mục tiêu . Xem hướng dẫn sử dụng để biết thêm thông tin của bạn.

JDK và Công cụ C++: để sử dụng công cụ của JDK hoặc bộ biên dịch C++, hệ thống xây dựng sẽ cung cấp một tập hợp các biến để sử dụng. Xem phần "Nhãn hiệu" biến cho chi tiết.

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

Lệnh genrules đượ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 một quy trình bị lỗi, 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 vài người 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 shell của người dùng môi trường không được truyền qua lệnh của quy tắc gen. Tuy nhiên, Bazel (nhưng không phải là 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 này trên bản dựng tiếp theo.

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

Hệ thống xây dựng tự động xoá mọi tệp đầu ra hiện có, nhưng sẽ tạo bất kỳ tệp mẹ nào 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. Họ không nên ghi dấu thời gian cho đầu ra và nên sử dụng thứ tự ổn định cho các tập hợp và bản đồ, cũng như chỉ ghi các đường dẫn tệp tương đối cho kết quả, không ghi đường dẫn tuyệt đối. Không tuân theo quy tắc này sẽ dẫn đến hành vi xây dựng không mong muốn (Bazel không xây dựng lại một quy tắc chung mà bạn từng nghĩ) và làm giảm hiệu suất của 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 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 mã hoá cứng và/hoặc đường dẫn tuyệt đối.
  • Viết một macro Starlark phổ biến trong trường hợp sử dụng genrules giống hoặc rất giống nhau trong nhiều địa điểm. Nếu quy tắc tạo sinh phức tạp, hãy cân nhắc triển khai quy tắc đó trong một tập lệnh hoặc dưới dạng Quy tắc Starlark. Điều này giúp cải thiện khả năng đọc cũng như khả năng kiểm thử.
  • 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 khi gỡ lỗi, nhưng bạn có thể dễ trở thành tiếng ồn; một quy tắc tạo sinh thành công phải im lặng. Mặt khác, một quy tắc gen không thành công sẽ phát ra thông báo lỗi tốt.
  • $$ evaluates to a $, a literal dollar-sign, so in order to invoke a shell command containing dollar-signs such as ls $(dirname $x), one must escape it thus: ls $$(dirname $$x).
  • Tránh tạo đường liên kết tượng trưng và thư mục. Bazel không sao chép thư mục/đường liên kết tượng trưng cấu trúc do genrules tạo ra và việc kiểm tra phần phụ thuộc của 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ể sử dụng nhãn của quy tắc gen 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: tham chiếu kết quả theo tên trong srcs của quy tắc tiêu thụ sẽ tránh được vô tình chọn các đầu ra khác của quy tắc tạo sinh, nhưng có thể trở nên tẻ nhạt nếu quy tắc tạo sinh 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ỳ đầu vào nào. "Tệp nhị phân" chạy bằng lệnh nà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 trình bày cách sử dụng filegroup và kết quả của một genrule khác. Lưu ý rằng bạn nên dùng $(SRCS) để thay thế lệnh $(location) rõ ràng cũng sẽ hoạt động; Ví dụ này sử dụng URL sau cho 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 BUILD khác quy tắ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; giá trị 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; sử dụng thuộc tính tools cho các trang đó.

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 quy tắc gen Command; chúng đượ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. Chiến lược phát hành đĩa đơn 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); hoặc là con đường của một cá nhân Có thể lấy //x:y mục tiêu của srcs 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

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 .

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ó tại cmd bằng cách sử dụng "Make" cụ thể theo quy tắc gen biến ($@, $(OUTS), $(@D) hoặc $(RULEDIR)) hoặc sử dụng Thay thế $(location).

cmd

String; giá trị mặc định là ""

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

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

cmd_bash

String; 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

String; 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 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 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 $(location)"Nhãn hiệu" thay thế, thì đường dẫn sẽ là đã mở rộng thành đường dẫn kiểu Windows (có dấu gạch chéo ngược).
cmd_ps

String; 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 chạy theo cách tương tự như cmd , với những 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 để 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 tập lệnh chưa được ký.
  • $errorActionPreference='Stop' – Trong trường hợp có nhiều lệnh được phân tách bằng ;, thao tác này sẽ thoát ngay lập tức nếu Powershell CmdLet không thành công, nhưng lệnh này KHÔNG hoạt động đối với lệnh bên ngoài.
  • $PSDefaultParameterValues['*:Encoding'] = 'utf8' – thay đổi chế độ mặc định và mã hoá từ utf-16 đến 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ì dữ liệu đầ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 nó.

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ì lựa chọn này sẽ buộc genrule chạy bằng cách sử dụng chế độ cài đặt "cục bộ" tức là không thực thi từ xa, không có hộp cát, không có trình thực thi liên tục.

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

message

String; 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 một điều gì đó nhạt nhẽo) nhưng bạn có thể cung cấp mục cụ thể hơn. Sử dụng thuộc tính này thay vì echo hoặc bản in khác trong lệnh cmd, vì lệnh này cho phép công cụ bản dựng kiểm soát liệu thông báo tiến trình đó có được in hay không.

output_licenses

Loại giấy phép; giá trị 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 chính sách này thành True, thì lựa chọn này sẽ khiến các tệp đầu ra được ghi vào bin thay vì thư mục genfiles.

tools

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

Danh sách các phần phụ thuộc công cụ cho quy tắc này. Xem định nghĩa của 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 genrules; chúng được tạo bằng cách sử dụng exec cấu hình, vì các công cụ này được thực thi trong bản dựng. Đường dẫn của một có thể lấy được tools mục tiêu //x:y riêng lẻ bằng cách sử dụng $(location //x:y).

Mọi *_binary hoặc công cụ mà cmd thực thi đều phải xuất hiện trong danh sách, không phải trong srcs, để đảm bảo các trang đó đượ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 về các quy tắc, hàm (bao gồm cả macro), các khía cạnh và nhà cung cấp được xác định hoặc xuất lại trong một .bzl hoặc .scl. Đầu ra của quy tắc này là một proto nhị phân ModuleInfo như đã xác định inch 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): A Proto nhị phân ModuleInfo.
  • name.textproto (chỉ được tạo nếu được yêu cầu rõ ràng): văn bản phiên bản proto 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. Ứng dụng này chủ yếu dành cho sử dụng nội bộ bằng Stardoc.

Đố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; giá trị mặc định là []

Danh sách các mục tiêu gói các tệp Starlark được load() quản lý src. Các mục tiêu này phải ở mức sử dụng bình thường 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 tệp Starlark trong DefaultInfo.

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 được phép Đã tạo load() tệp.

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 được load() tệp được tạo.

render_main_repo_name

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

Nếu giá trị là true, hãy hiển thị nhãn trong kho lưu trữ chính ở tài liệu được tạo ra với thành phần kho lưu trữ (nói cách khác, //foo:bar.bzl sẽ được phát 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 đã bật Bzlmod) hoặc từ workspace(name = ...) trong tệp WORKSPACE của kho lưu trữ chính.

Thuộc tính này phải được đặt 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à để True khi tạo tài liệu cho các tệp Starlark được sử dụng từ các kho lưu trữ khác.

symbol_names

Danh sách các chuỗi; giá trị 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 đã xuất (hoặc cấu trúc lồng ghép chúng) để trích xuất tài liệu. Ở đây, nhà quảng cáo đủ điều kiện name là tên mà 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 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 công khai (nói cách khác, phần đầu tiên ký tự của mỗi thành phần của tên đủ điều kiện có dạng chữ cái, không phải là "_");
    1. hoặc danh sách symbol_names trống (đây là danh sách mặc định chữ hoa), 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 trong đó thực thể được lồng nhau, 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 kiểm thử được xem là "hữu ích" cho con người. Chiến dịch này cho phép các dự án xác định tập hợp các bài 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 tra", "các chương trình kiểm thử của chúng tôi chương trình kiểm thử nghiêm ngặt" hoặc "tất cả các thử nghiệm nhỏ". Lệnh bazel test tuân theo cách sắp xếp này of tổ chức: Đối với lệnh gọi như bazel test //some/test:suite, trước tiên Bazel liệt kê tất cả các mục tiêu kiểm thử được mục tiêu //some/test:suite đưa vào theo cách bắc cầu (chúng ta gọi là "mở rộng test_suite"), sau đó Bazel 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 các chuỗi; không thể định cấu hình; giá trị mặc định là []

Danh sách thẻ văn bản, chẳng hạ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 "-" đều được coi là thẻ phủ định. Chiến lược phát hành đĩa đơn trước "-" không được xem là một phần của thẻ, vì vậy thẻ bộ của "-small" khớp với "nhỏ" của thử nghiệm kích thước. Tất cả các thẻ khác đều được xem xét các thẻ khẳng định.

Theo tuỳ chọn, để làm cho thẻ khẳng định rõ ràng hơn, thẻ cũng có thể bắt đầu bằng "+" mà sẽ không được đánh giá như một phần của văn bản thẻ. Nó chỉ làm cho sự phân biệt tích cực và tiêu cực dễ đọc hơn.

Chỉ thử nghiệm những quy tắc khớp với tất cả thẻ dương và không có thẻ phủ định nào sẽ được đưa vào bộ thử nghiệm. Lưu ý rằng điều này không có nghĩa là việc kiểm tra lỗi đối với các phần phụ thuộc trên các chương trình kiểm thử được lọc ra sẽ bị bỏ qua; phần phụ thuộc trên bị bỏ qua các bài kiểm thử 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ề khả năng hiển thị).

Từ khoá thẻ manual được xử lý khác với cách ở trên bởi "mở rộng test_suite" được thực hiện bằng lệnh bazel test đối với lời gọi liên quan đến ký tự đại diện mẫu mục tiêu. Ở đó, test_suite mục tiêu được gắn thẻ "thủ công" được lọc ra (và do đó không được đã mở rộng). Hành vi này phù hợp với cách bazel buildbazel test xử lý các mẫu đích ký tự đại diện nói chung. Lưu ý rằng khác hoàn toàn với cách hoạt động của bazel query 'tests(E)', vì các bộ ứng dụng luôn được mở rộng bởi hàm truy vấn tests, bất kể Thẻ manual.

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

Trường hợp bạn cần một test_suite chứa các bài kiểm thử có các thẻ loại trừ lẫn nhau (ví dụ: mọi thử nghiệm vừa và nhỏ), bạn sẽ phải tạo ba tệp test_suite quy tắc: một cho mọi kiểm thử nhỏ, một cho mọi kiểm thử trung bình và một cho mọi kiểm thử trung bình hai câu 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ữ. Không Tuy nhiên, các mục tiêu *_binary được chấp nhận, ngay cả khi chạy thử nghiệm. 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 các test_suite thì các phép kiểm thử bên trong các kết quả đó sẽ không được lọc bởi test_suite này (chúng đượ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 này sẽ mặc định thà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 tuân theo chế độ lọc tag.