- Sử dụng
- Biến được xác định trước
- Các biến genrule được xác định trước
- Biến đường dẫn nguồn/đầu ra được xác định trước
- Biến tuỳ chỉnh
"Biến Make" là một lớp đặc biệt của các biến chuỗi có thể mở rộng, có sẵn cho các thuộc tính được đánh dấu là "Chịu sự thay thế của "Biến Make"".
Ví dụ: bạn có thể dùng các mục 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ả các biến được xác định trước (có sẵn cho tất cả các mục tiêu) và các biến tuỳ chỉnh (được xác định trong các mục tiêu phụ thuộc và chỉ có sẵn cho các mục tiêu phụ thuộc vào chúng).
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 khớp với GNU Make.
Sử dụng
Các thuộc tính được đánh dấu là "Có thể thay thế bằng "Biến"" có thể tham chiếu đến biến "Nhãn hiệu" 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 giá trị của FOO
. Nếu giá trị đó là "bar"
, thì chuỗi cuối cùng sẽ là:
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 các biến "Make" có tên là các 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"
Để ghi $
dưới dạng một chuỗi ký tự (tức là để ngăn việc mở rộng biến), hãy ghi $$
.
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
'stools
attribute. 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
'souts
list. If you have only one output file, you can also use$@
.-
SRCS
: Thegenrule
'ssrcs
list (or more precisely: the path names of the files corresponding to labels in thesrcs
list). 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 thegenfiles
orbin
tree. For//my/pkg:my_genrule
this 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 thegenfiles
tree, even if all output files are in the same subdirectory!Note: Use
RULEDIR
over@D
becauseRULEDIR
has 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/tmp
will 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 )
rồi 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 được xác định trước
Các biến được xác định trước
execpath
,execpaths
,rootpath
,rootpaths
,location
vàlocations
lấy 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 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à đầ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 tạo trong thư mục được liên kết bằng symlink
bazel-myproject
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 thực thi của tệp này (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 tạo bản dựng có thể dùng để tìm tệp.Các tệp đầu ra được dàn xếp tương tự, nhưng cũng có tiền tố là đường dẫn con
bazel-out/cpu-compilation_mode/bin
(hoặc đối với đầu ra của các công cụ:bazel-out/cpu-opt-exec-hash/bin
). Trong ví dụ trên,//testapp:app
là một công cụ vì nó xuất hiện trong thuộc tínhtools
củashow_app_output
. Vì vậy, tệp đầu raapp
của nó được ghi vàobazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/app
. Do đó, đường dẫn thực thi làbazel-out/cpu-opt-exec-hash/bin/testapp/app
. Tiền tố bổ sung này giúp bạn có thể tạo cùng một mục tiêu cho, chẳng hạn như, 2 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 chính xác một tệp. Đối với các nhãn đại diện cho tệp nguồn, điều này tự động đúng. Đối với các nhãn đại diện cho quy tắc, quy tắc phải tạo chính xác một đầu ra. Nếu giá trị này là false hoặc nhãn bị sai định dạng, thì bản dựng sẽ không thành công và gặp lỗi.
-
rootpath
: Biểu thị đường dẫn mà tệp nhị phân đã tạo 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--enable_runfiles
được bật. Theo mặc định, chế độ này không được bật trên Windows. Hãy sử dụngrlocationpath
để thay thế nhằm hỗ trợ đa nền tảng.Điều này tương tự như
execpath
như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.source
vàapp
đều sử dụng các đường dẫn tương đối thuần tuý trong không gian làm việc:testapp/empty.source
vàtestapp/app
.rootpath
của một tệp trong kho lưu trữ bên ngoàirepo
sẽ bắt đầu bằng../repo/
, theo sau là đường dẫn tương đối của kho lưu trữ.Thao tác này có cùng yêu cầu "chỉ có một đầu ra" như
execpath
. -
rlocationpath
: Đường dẫn mà một tệp nhị phân đã tạo có thể truyền đến hàmRlocation
của một thư viện runfiles để tìm một 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.Thư mục 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.source
vàapp
sẽ dẫn đến các đường dẫn sau:myproject/testapp/empty.source
vàmyproject/testapp/app
.rlocationpath
của một tệp trong kho lưu trữ bên ngoàirepo
sẽ bắt đầu bằngrepo/
, theo sau là đường dẫn tương đối của kho lưu trữ.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 các 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
, có ưu điểm là hoạt động trên mọi nền tảng, ngay cả khi không có thư mục runfiles.Thao tác này có cùng yêu cầu "chỉ có một đầu ra" như
execpath
. -
location
: Từ đồng nghĩa vớiexecpath
hoặcrootpath
, tuỳ thuộc vào thuộc tính được mở rộng. Đây là hành vi cũ trước Starlark và không được khuyến khích trừ phi bạn thực sự biết hành vi này có tác dụng gì đối với một quy tắc cụ thể. Hãy xem #2475 để biết thông tin chi tiết.
execpaths
, rootpaths
, rlocationpaths
và locations
lần lượt là các biến thể số nhiều của execpath
, rootpath
, rlocationpath
và location
. Chúng hỗ trợ các nhãn tạo ra nhiều đầu ra. Trong trường hợp này, mỗi đầu ra sẽ được liệt kê riêng biệt bằng một khoảng trắng. Các quy tắc không có đầu ra và nhãn bị lỗi sẽ tạo ra lỗi bản dựng.
Tất cả nhãn được tham chiếu phải xuất hiện trong các tệp đầu ra srcs
của mục tiêu sử dụng hoặc deps
. Nếu không, bản dựng sẽ không thành công. Các mục tiêu C++ cũng có thể tham chiếu đến các nhãn trong data
.
Nhãn không cần phải ở dạng chính tắc: foo
, :foo
và //somepkg:foo
đều được.
Biến tuỳ chỉnh
Mọi thuộc tính được đánh dấu là "Chịu sự thay thế của"Biến thương hiệu"" đều có thể tham chiếu đến các biến "Thương hiệu" tuỳ chỉnh, nhưng chỉ trên những 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.
Theo phương pháp hay nhất, tất cả các biến phải là biến tuỳ chỉnh, trừ phi có lý do thực sự chính đáng để đưa chúng 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ó thể tốn kém để cung cấp các biến tiêu thụ mục tiêu mà bạn có thể không quan tâm.
Các biến của chuỗi công cụ C++
Các quy tắc sau được xác định trong các quy tắc chuỗi công cụ C++ và có sẵn 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ủa chúng. Chúng 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 cùng lúc 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 sẽ được áp dụng để đảm bảo bạn đặt đúng đầu vào, đầu ra và cờ dòng lệnh trên mỗi hành động có thể có trong số nhiều hành động được tạo nội bộ.
Đây là cơ chế dự phòng mà các chuyên gia ngôn ngữ sẽ sử dụng trong một số trường hợp hiếm gặp. Nếu bạn muốn sử dụng các quy tắc 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_FLAGS
kết hợp vớiCC
. Bạn tự chịu rủi ro nếu không làm như vậy. 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ằng genrules. Cụ thể, tệp này chứa các cờ để chọn cấu trúc chính xác nếuCC
hỗ trợ nhiều cấu trúc.-
DUMPBIN
: Microsoft COFF Binary File Dumper (dumpbin.exe) của Microsoft Visual Studio. -
NM
: Lệnh "nm" từ crosstool. -
OBJCOPY
: Lệnh objcopy trong cùng một bộ với trình biên dịch C/C++. -
STRIP
: Lệnh xoá khỏi cùng một bộ như trình biên dịch C/C++.
Biến chuỗi công cụ Java
Các mục sau đây được xác định trong các quy tắc của chuỗi công cụ Java và có sẵn 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ụ tương đương của máy chủ lưu trữ).
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 phương pháp tinh vi hơn nhiều để biên dịch và đóng gói Java so với những gì các công cụ thượng nguồn có thể thể hiện, chẳng hạn như Jar giao diện, Jar giao diện tiêu đề và các phương thức triển khai hợp nhất và đóng gói Jar được tối ưu hoá cao.
Đây là cơ chế dự phòng mà các chuyên gia ngôn ngữ sẽ sử dụng trong một số trường hợp hiếm gặp. Nếu bạn muốn sử dụng các quy tắc này, vui lòng liên hệ với nhóm phát triển Bazel trước.
-
JAVA
: Lệnh "java" (một máy ảo Java). Tránh trường hợp này và thay vào đó hãy sử dụng quy tắcjava_binary
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 đang hoạt động 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".
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 trình cung cấp TemplateVariableInfo. Mọi quy tắc phụ thuộc vào các quy tắc này thông qua thuộc tính toolchains
đều có thể đọc các giá trị của quy tắc: