- Sử dụng
- Biến xác định trước
- Biến genrule xác định trước
- Biến đường dẫn nguồn/đầu ra xác định trước
- Biến tuỳ chỉnh
Biến "Make" là một lớp đặc biệt gồm các biến chuỗi có thể mở rộng, dùng cho các thuộc tính được đánh dấu là "Subject to 'Make variable' substitution" (Chịu sự thay thế của "Biến Make") .
Ví dụ: bạn có thể dùng các biến này để chèn các đường dẫn chuỗi công cụ cụ thể vào các thao tác xây dựng do người dùng tạo.
Bazel cung cấp cả biến xác định trước (dùng cho tất cả mục tiêu) và biến tuỳ chỉnh (được xác định trong các mục tiêu phụ thuộc và chỉ dùng cho các mục tiêu phụ thuộc vào các biến này).
Lý do cho thuật ngữ "Make" là do lịch sử: cú pháp và ngữ nghĩa của các biến này ban đầu được dự định là khớp với GNU Make.
Sử dụng
Các thuộc tính được đánh dấu là "Subject to 'Make variable' substitution" có thể
tham chiếu đến biến "Make" FOO như sau:
my_attr = "prefix $(FOO) suffix"
Nói cách khác, mọi chuỗi con khớp với $(FOO) đều được mở rộng
thành FOO's value. Nếu giá trị đó là "bar", thì chuỗi cuối cùng
sẽ trở thành:
my_attr = "prefix bar suffix"
Nếu FOO không tương ứng với một biến mà mục tiêu sử dụng biết, thì Bazel sẽ gặp lỗi.
Bạn cũng có thể tham chiếu đến các biến "Make" có tên là ký hiệu không phải chữ cái, chẳng hạn như
@, chỉ bằng cách sử dụng dấu đô la mà không cần
dấu ngoặc đơn. Ví dụ:
my_attr = "prefix $@ suffix"
Để viết $ dưới dạng một chuỗi ký tự (tức là để ngăn việc mở rộng biến), hãy viết $$.
Predefined variables
Predefined "Make" variables can be referenced by any attribute marked as "Subject to 'Make variable' substitution" on any target.
To see the list of these variables and their values for a given set of build options, run
bazel info --show_make_env [build options]
and look at the top output lines with capital letters.
See an example of predefined variables.
Toolchain option variables
COMPILATION_MODE:fastbuild,dbg, oropt. (more details)
Path variables
-
BINDIR: The base of the generated binary tree for the target architecture.Note that a different tree may be used for programs that run during the build on the host architecture, to support cross-compiling.
If you want to run a tool from within a
genrule, the recommended way to get its path is$(execpath toolname), where toolname must be listed in thegenrule'stoolsattribute. GENDIR: The base of the generated code tree for the target architecture.
Machine architecture variables
-
TARGET_CPU: The target architecture's CPU, e.g.k8.
Predefined genrule variables
The following are specially available to genrule's
cmd attribute and are
generally important for making that attribute work.
See an example of predefined genrule variables.
OUTS: Thegenrule'soutslist. If you have only one output file, you can also use$@.-
SRCS: Thegenrule'ssrcslist (or more precisely: the path names of the files corresponding to labels in thesrcslist). If you have only one source file, you can also use$<. -
<:SRCS, if it is a single file. Else triggers a build error. -
@:OUTS, if it is a single file. Else triggers a build error. -
RULEDIR: The output directory of the target, that is, the directory corresponding to the name of the package containing the target under thegenfilesorbintree. For//my/pkg:my_genrulethis always ends inmy/pkg, even if//my/pkg:my_genrule's outputs are in subdirectories. -
@D: The output directory. If outs has one entry, this expands to the directory containing that file. If it has multiple entries, this expands to the package's root directory in thegenfilestree, even if all output files are in the same subdirectory!Note: Use
RULEDIRover@DbecauseRULEDIRhas simpler semantics and behaves the same way regardless of the number of output files.If the genrule needs to generate temporary intermediate files (perhaps as a result of using some other tool like a compiler), it should attempt to write them to
@D(although/tmpwill also be writable) and remove them before finishing.Especially avoid writing to directories containing inputs. They may be on read-only filesystems. Even if not, doing so would trash the source tree.
Note: If the filenames corresponding to the input labels or the output
filenames contain spaces, ', or other special characters (or your
genrule is part of a Starlark macro which downstream users may invoke on such
files), then $(SRCS) and $(OUTS) are not suitable
for interpolation into a command line, as they do not have the semantics that
"${@}" would in Bash.
One workaround is to convert to a Bash array, with
mapfile SRCS <<< "$$(sed -e 's/ /\\n/g' <<'genrule_srcs_expansion' $(SRC) genrule_srcs_expansion )và sau đó sử dụng"$$\{SRCS[@]}"trong các dòng lệnh tiếp theo thay cho$(SRCS). Một lựa chọn mạnh mẽ hơn là viết một quy tắc Starlark.Biến đường dẫn nguồn/đầu ra xác định trước
Các biến xác định trước
execpath,execpaths,rootpath,rootpaths,location, vàlocationsnhận các tham số nhãn (ví dụ:$(execpath //foo:bar)) và thay thế các đường dẫn tệp được biểu thị bằng nhãn đó.Đối với các tệp nguồn, đây là đường dẫn tương đối so với thư mục gốc của không gian làm việc. Đối với các tệp là kết quả đầu ra của quy tắc, đây là đường dẫn đầu ra của tệp (xem phần giải thích về tệp đầu ra bên dưới).
-
execpath: Biểu thị đường dẫn bên dưới execroot nơi Bazel chạy các thao tác xây dựng.Trong ví dụ trên, Bazel chạy tất cả các thao tác xây dựng trong thư mục được liên kết bằng
bazel-myprojectliên kết tượng trưng trong thư mục gốc của không gian làm việc. Tệp nguồnempty.sourceđược liên kết tại đường dẫnbazel-myproject/testapp/empty.source. Vì vậy, đường dẫn exec của tệp (là đường dẫn con bên dưới thư mục gốc) làtestapp/empty.source. Đây là đường dẫn mà các thao tác xây dựng có thể dùng để tìm tệp.Các tệp đầu ra được dàn dựng tương tự, nhưng cũng được thêm tiền tố bằng đường dẫn con
bazel-out/cpu-compilation_mode/bin(hoặc đối với kết quả đầu ra của công cụ:bazel-out/cpu-opt-exec-hash/bin). Trong ví dụ trên,//testapp:applà một công cụ vì công cụ này xuất hiện trong thuộc tínhtoolscủashow_app_output. Vì vậy, tệp đầu raappđược ghi vàobazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/app. Do đó, đường dẫn exec làbazel-out/cpu-opt-exec-hash/bin/testapp/app. Tiền tố bổ sung này giúp bạn có thể xây dựng cùng một mục tiêu cho, chẳng hạn như hai CPU khác nhau trong cùng một bản dựng mà không làm kết quả bị ghi đè lẫn nhau.Nhãn được truyền đến biến này phải đại diện cho đúng một tệp. Đối với các nhãn đại diện cho tệp nguồn, điều này sẽ tự động đúng. Đối với các nhãn đại diện cho quy tắc, quy tắc phải tạo đúng một kết quả đầu ra. Nếu điều này là sai hoặc nhãn bị định dạng sai, thì bản dựng sẽ gặp lỗi.
-
rootpath: Biểu thị đường dẫn mà một tệp nhị phân đã xây dựng có thể dùng để tìm phần phụ thuộc trong thời gian chạy so với thư mục con của thư mục runfiles tương ứng với kho lưu trữ chính. Lưu ý: Điều này chỉ hoạt động nếu bạn bật--enable_runfiles, theo mặc định, Windows không bật tính năng này. Thay vào đó, hãy sử dụngrlocationpathđể hỗ trợ nhiều nền tảng.Điều này tương tự như
execpathnhưng sẽ loại bỏ các tiền tố cấu hình được mô tả ở trên. Trong ví dụ ở trên, điều này có nghĩa là cảempty.sourcevàappđều sử dụng các đường dẫn tương đối so với không gian làm việc thuần tuý:testapp/empty.sourcevàtestapp/app.rootpathcủa một tệp trong kho lưu trữ bên ngoàireposẽ bắt đầu bằng../repo/, tiếp theo là đường dẫn tương đối so với kho lưu trữ.Điều này có cùng yêu cầu "chỉ một kết quả đầu ra" như
execpath. -
rlocationpath: Đường dẫn mà một tệp nhị phân đã xây dựng có thể truyền đến hàmRlocationcủa thư viện runfiles để tìm phần phụ thuộc trong thời gian chạy, trong thư mục runfiles (nếu có) hoặc bằng cách sử dụng tệp kê khai runfiles.Điều này tương tự như
rootpathở chỗ không chứa tiền tố cấu hình, nhưng khác ở chỗ luôn bắt đầu bằng tên của kho lưu trữ. Trong ví dụ ở trên, điều này có nghĩa làempty.sourcevàappsẽ tạo ra các đường dẫn sau:myproject/testapp/empty.sourcevàmyproject/testapp/app.rlocationpathcủa một tệp trong kho lưu trữ bên ngoàireposẽ bắt đầu bằngrepo/, tiếp theo là đường dẫn tương đối so với kho lưu trữ.Việc truyền đường dẫn này đến một tệp nhị phân và phân giải đường dẫn đó thành đường dẫn hệ thống tệp bằng cách sử dụng thư viện runfiles là phương pháp ưu tiên để tìm các phần phụ thuộc trong thời gian chạy. So với
rootpath, phương pháp này có ưu điểm là hoạt động trên tất cả các nền tảng và ngay cả khi thư mục runfiles không có sẵn.Điều này có cùng yêu cầu "chỉ một kết quả đầu ra" như
execpath. -
location: Từ đồng nghĩa choexecpathhoặcrootpath, tuỳ thuộc vào thuộc tính đang được mở rộng. Đây là hành vi cũ trước Starlark và bạn không nên sử dụng trừ phi bạn thực sự biết hành vi này hoạt động như thế nào đối với một quy tắc cụ thể. Xem #2475 để biết thông tin chi tiết.
execpaths, rootpaths, rlocationpaths,
và locations là các biến thể số nhiều của execpath,
rootpath, rlocationpath, vàlocation,
tương ứng. Các biến thể này hỗ trợ các nhãn tạo ra nhiều kết quả đầu ra, trong trường hợp đó
mỗi kết quả đầu ra được liệt kê và phân tách bằng dấu cách. Các quy tắc không có kết quả đầu ra và nhãn bị định dạng sai
sẽ tạo ra lỗi bản dựng.
Tất cả các nhãn được tham chiếu phải xuất hiện trong srcs,
tệp đầu ra hoặc deps. Nếu không, bản dựng sẽ gặp lỗi. Các mục tiêu C++ cũng có thể tham chiếu đến các nhãn trong data.
Các nhãn không cần phải ở dạng chính tắc: foo, :foo
và //somepkg:foo đều ổn.
Biến tuỳ chỉnh
Mọi thuộc tính được đánh dấu là "Subject to 'Make variable' substitution" (Chịu sự thay thế của "Biến Make") đều có thể tham chiếu đến các biến "Make" tuỳ chỉnh, nhưng chỉ trên các mục tiêu phụ thuộc vào các mục tiêu khác xác định các biến này.
Tốt nhất là tất cả các biến đều phải là biến tuỳ chỉnh, trừ phi có lý do thực sự chính đáng để đưa các biến đó vào Bazel cốt lõi. Điều này giúp Bazel không phải tải các phần phụ thuộc có khả năng tốn kém để cung cấp các biến mà các mục tiêu sử dụng có thể không quan tâm.
Biến chuỗi công cụ C++
Các biến sau được xác định trong các quy tắc chuỗi công cụ C++ và dùng cho mọi quy tắc
đặt toolchains =
["@bazel_tools//tools/cpp:toolchain_type"]
Một số quy tắc, chẳng hạn như java_binary, ngầm
bao gồm chuỗi công cụ C++ trong định nghĩa quy tắc. Các quy tắc này sẽ tự động kế thừa các biến này.
Các quy tắc C++ tích hợp phức tạp hơn nhiều so với "chạy trình biên dịch trên đó". Để hỗ trợ các chế độ biên dịch đa dạng như *SAN, ThinLTO, có/không có mô-đun và các tệp nhị phân được tối ưu hoá cẩn thận đồng thời với các bài kiểm thử chạy nhanh trên nhiều nền tảng, các quy tắc tích hợp phải nỗ lực rất nhiều để đảm bảo các dữ liệu đầu vào, kết quả đầu ra và cờ dòng lệnh chính xác được đặt trên mỗi thao tác có khả năng được tạo nội bộ.
Các biến này là cơ chế dự phòng để các chuyên gia ngôn ngữ sử dụng trong những trường hợp hiếm gặp. Nếu bạn muốn sử dụng các biến này, vui lòng liên hệ với nhóm phát triển Bazel trước.
ABI: Phiên bản ABI C++.-
AR: Lệnh "ar" từ crosstool. -
C_COMPILER: Giá trị nhận dạng trình biên dịch C/C++, ví dụ:llvm. -
CC: Lệnh trình biên dịch C và C++.Bạn nên luôn sử dụng
CC_FLAGSkết hợp vớiCC. Nếu không làm như vậy, bạn sẽ phải chịu rủi ro. CC_FLAGS: Một tập hợp cờ tối thiểu để trình biên dịch C/C++ có thể sử dụng được bởi genrules. Cụ thể, tập hợp này chứa các cờ để chọn cấu trúc chính xác nếuCChỗ trợ nhiều cấu trúc.-
DUMPBIN: Microsoft COFF Binary File Dumper (dumpbin.exe) từ từ Microsoft Visual Studio. -
NM: Lệnh "nm" từ crosstool. -
OBJCOPY: Lệnh objcopy từ cùng một bộ như trình biên dịch C/C++ -
STRIP: Lệnh strip từ cùng một bộ như trình biên dịch C/C++
Biến chuỗi công cụ Java
Các biến sau được xác định trong các quy tắc chuỗi công cụ Java và dùng cho mọi quy tắc
đặt toolchains =
["@rules_java//toolchains:current_java_runtime"] (hoặc
"@rules_java//toolchains:current_host_java_runtime"
cho chuỗi công cụ máy chủ tương đương).
Bạn không nên sử dụng trực tiếp hầu hết các công cụ trong JDK. Các quy tắc Java tích hợp sử dụng các phương pháp phức tạp hơn nhiều để biên dịch và đóng gói Java so với các công cụ ngược dòng có thể biểu thị, chẳng hạn như Jars giao diện, Jars giao diện tiêu đề và các cách triển khai đóng gói và hợp nhất Jar được tối ưu hoá cao.
Các biến này là cơ chế dự phòng để các chuyên gia ngôn ngữ sử dụng trong những trường hợp hiếm gặp. Nếu bạn muốn sử dụng các biến này, vui lòng liên hệ với nhóm phát triển Bazel trước.
-
JAVA: Lệnh "java" (máy ảo Java ). Tránh sử dụng lệnh này và thay vào đó, hãy sử dụng quy tắcjava_binaryrule nếu có thể. Có thể là đường dẫn tương đối. Nếu phải thay đổi thư mục trước khi gọijava, bạn cần nắm bắt thư mục làm việc trước khi thay đổi. JAVABASE: Thư mục cơ sở chứa các tiện ích Java. Có thể là đường dẫn tương đối. Thư mục này sẽ có một thư mục con "bin" subdirectory.
Biến do Starlark xác định
Người viết quy tắc và chuỗi công cụ có thể xác định
các biến hoàn toàn tuỳ chỉnh bằng cách trả về một
TemplateVariableInfo. Mọi quy tắc phụ thuộc vào các biến này thông qua thuộc tính
toolchains đều có thể đọc giá trị của các biến đó: