- Uso
- Variáveis predefinidas
- Variáveis predefinidas de genrule
- Variáveis predefinidas de caminho de origem/saída
- Variáveis personalizadas
As variáveis "Make" são uma classe especial de variáveis de string expansíveis disponíveis para atributos marcados como "Sujeito à substituição da variável 'Make'".
Elas podem ser usadas, por exemplo, para injetar caminhos específicos de conjunto de ferramentas em ações de build criadas pelo usuário.
O Bazel fornece variáveis predefinidas, que estão disponíveis para todos os destinos, e variáveis personalizadas, que são definidas em destinos de dependência e estão disponíveis apenas para destinos que dependem delas.
O motivo do termo "Make" é histórico: a sintaxe e a semântica dessas variáveis foram originalmente criadas para corresponder ao GNU Make.
Usar
Atributos marcados como "Sujeito à substituição da variável "Make"" podem
referenciar a variável FOO
"Make" da seguinte maneira:
my_attr = "prefix $(FOO) suffix"
Em outras palavras, qualquer substring que corresponda a $(FOO)
será expandida
para o valor de FOO
. Se esse valor for "bar"
, a string
final vai ser:
my_attr = "prefix bar suffix"
Se FOO
não corresponder a uma variável conhecida pelo destino
de consumo, o Bazel falhará com um erro.
Variáveis "Make" com nomes que são símbolos que não são letras, como
@
, também podem ser referenciadas usando apenas um cifrão, sem
parênteses. Exemplo:
my_attr = "prefix $@ suffix"
Para gravar $
como uma string literal (ou seja, para evitar a expansão
de variáveis), grave $$
.
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 )
e use"$$\{SRCS[@]}"
em linhas de comando subsequentes no lugar de$(SRCS)
. Uma opção mais robusta é escrever uma regra do Starlark.Variáveis de caminho de origem/saída predefinidas
As variáveis predefinidas
execpath
,execpaths
,rootpath
,rootpaths
,location
elocations
usam parâmetros de rótulo (por exemplo,$(execpath //foo:bar)
) e substituem os caminhos de arquivo indicados por esse rótulo.Para arquivos de origem, esse é o caminho relativo à raiz do espaço de trabalho. Para arquivos que são saídas de regras, esse é o caminho de saída do arquivo. Consulte a explicação sobre arquivos de saída abaixo.
-
execpath
: denota o caminho abaixo do execroot em que o Bazel executa ações de build.No exemplo acima, o Bazel executa todas as ações de build no diretório vinculado pelo link simbólico
bazel-myproject
na raiz do espaço de trabalho. O arquivo de origemempty.source
está vinculado no caminhobazel-myproject/testapp/empty.source
. Portanto, o caminho de execução (que é o subcaminho abaixo da raiz) étestapp/empty.source
. Esse é o caminho que as ações de build podem usar para encontrar o arquivo.Os arquivos de saída são organizados de maneira semelhante, mas também têm o prefixo do subcaminho
bazel-out/cpu-compilation_mode/bin
(ou para as saídas de ferramentas:bazel-out/cpu-opt-exec-hash/bin
). No exemplo acima,//testapp:app
é uma ferramenta porque aparece no atributotools
deshow_app_output
. Portanto, o arquivo de saídaapp
é gravado embazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/app
. O caminho de execução ébazel-out/cpu-opt-exec-hash/bin/testapp/app
. Esse prefixo extra permite criar o mesmo destino para, digamos, duas CPUs diferentes no mesmo build sem que os resultados se sobreponham.O rótulo transmitido para essa variável precisa representar exatamente um arquivo. Para rótulos que representam arquivos de origem, isso é automaticamente verdadeiro. Para rótulos que representam regras, a regra precisa gerar exatamente uma saída. Se esse valor for falso ou o rótulo estiver malformado, o build vai falhar com um erro.
-
rootpath
: denota o caminho que um binário criado pode usar para encontrar uma dependência no momento da execução em relação ao subdiretório do diretório de arquivos de execução correspondente ao repositório principal. Observação:isso só funciona se o--enable_runfiles
estiver ativado, o que não é o caso do Windows por padrão. Userlocationpath
para oferecer suporte a várias plataformas.Isso é semelhante a
execpath
, mas remove os prefixos de configuração descritos acima. No exemplo acima, isso significa queempty.source
eapp
usam caminhos puramente relativos ao espaço de trabalho:testapp/empty.source
etestapp/app
.O
rootpath
de um arquivo em um repositório externorepo
vai começar com../repo/
, seguido pelo caminho relativo ao repositório.Ele tem os mesmos requisitos de "apenas uma saída" que
execpath
. -
rlocationpath
: o caminho que um binário criado pode transmitir para a funçãoRlocation
de uma biblioteca de runfiles para encontrar uma dependência no momento da execução, no diretório de runfiles (se disponível) ou usando o manifesto de runfiles.Isso é semelhante a
rootpath
, porque não contém prefixos de configuração, mas é diferente porque sempre começa com o nome do repositório. No exemplo acima, isso significa queempty.source
eapp
resultam nos seguintes caminhos:myproject/testapp/empty.source
emyproject/testapp/app
.O
rlocationpath
de um arquivo em um repositório externorepo
vai começar comrepo/
, seguido pelo caminho relativo ao repositório.Transmitir esse caminho para um binário e resolvê-lo em um caminho do sistema de arquivos usando as bibliotecas de runfiles é a abordagem preferencial para encontrar dependências no ambiente de execução. Em comparação com
rootpath
, ele tem a vantagem de funcionar em todas as plataformas e mesmo que o diretório de arquivos de execução não esteja disponível.Ele tem os mesmos requisitos de "apenas uma saída" que
execpath
. -
location
: um sinônimo deexecpath
ourootpath
, dependendo do atributo que está sendo expandido. Esse é um comportamento legado anterior ao Starlark e não é recomendado, a menos que você realmente saiba o que ele faz para uma regra específica. Consulte #2475 para mais detalhes.
execpaths
, rootpaths
, rlocationpaths
e locations
são as variações plurais de execpath
,
rootpath
, rlocationpath
e location
,
respectivamente. Eles oferecem suporte a rótulos que produzem várias saídas. Nesse caso, cada saída é listada separada por um espaço. Regras de saída zero e rótulos
malformados produzem erros de build.
Todos os rótulos referenciados precisam aparecer no srcs
,
nos arquivos de saída ou no deps
do destino consumidor. Caso contrário, o build falha. Os destinos do C++ também
podem referenciar rótulos em data
.
Os identificadores não precisam estar no formato canônico: foo
, :foo
e //somepkg:foo
são todos aceitáveis.
Variáveis personalizadas
As variáveis "Make" personalizadas podem ser referenciadas por qualquer atributo marcado como "Sujeito à substituição da variável "Make"", mas apenas em segmentos que dependem de outros que definem essas variáveis.
Como prática recomendada, todas as variáveis precisam ser personalizadas, a menos que haja um motivo muito bom para incorporá-las ao núcleo do Bazel. Isso evita que o Bazel precise carregar dependências potencialmente caras para fornecer variáveis que consomem tarets que não se importam.
Variáveis da cadeia de ferramentas do C++
As seguintes regras são definidas nas regras da cadeia de ferramentas C++ e estão disponíveis para qualquer regra
que defina toolchains =
["@bazel_tools//tools/cpp:toolchain_type"]
.
Algumas regras, como java_binary
, incluem implicitamente
a cadeia de ferramentas C++ na definição da regra. Elas herdam essas variáveis
automaticamente.
As regras integradas do C++ são muito mais sofisticadas do que "executar o compilador nele". Para oferecer suporte a modos de compilação tão diversos quanto *SAN, ThinLTO, com/sem módulos e binários cuidadosamente otimizados, ao mesmo tempo em que executam testes rápidos em várias plataformas, as regras integradas vão longe para garantir que as entradas, saídas e flags de linha de comando corretas sejam definidas em cada uma das ações potencialmente geradas internamente.
Essas variáveis são um mecanismo alternativo para uso por especialistas em linguagem em casos raros. Se você tiver vontade de usá-los, entre em contato com os desenvolvedores do Bazel primeiro.
ABI
: a versão da ABI do C++.-
AR
: o comando "ar" do crosstool. -
C_COMPILER
: identifica o compilador C/C++, por exemplo,llvm
. -
CC
: o comando do compilador C e C++.É altamente recomendável usar sempre
CC_FLAGS
em combinação comCC
. Se você não fizer isso, será por sua conta e risco. CC_FLAGS
: um conjunto mínimo de flags para que o compilador C/C++ possa ser usado por genrules. Em particular, ele contém flags para selecionar a arquitetura correta seCC
for compatível com várias arquiteturas.-
DUMPBIN
: Microsoft COFF Binary File Dumper (dumpbin.exe) do Microsoft Visual Studio. -
NM
: o comando "nm" do crosstool. -
OBJCOPY
: o comando objcopy do mesmo pacote do compilador C/C++. -
STRIP
: o comando de remoção do mesmo pacote do compilador C/C++.
Variáveis da cadeia de ferramentas do Java
As seguintes regras são definidas nas regras do conjunto de ferramentas do Java e estão disponíveis para qualquer regra
que defina toolchains =
["@rules_java//toolchains:current_java_runtime"]
(ou
"@rules_java//toolchains:current_host_java_runtime"
para o equivalente do conjunto de ferramentas do host).
A maioria das ferramentas do JDK não deve ser usada diretamente. As regras Java integradas usam abordagens muito mais sofisticadas para a compilação e o empacotamento do Java do que as ferramentas upstream podem expressar, como frascos de interface, frascos de interface de cabeçalho e implementações de mesclagem e empacotamento de frascos altamente otimizadas.
Essas variáveis são um mecanismo alternativo para uso por especialistas em linguagem em casos raros. Se você tiver vontade de usá-los, entre em contato com os desenvolvedores do Bazel primeiro.
-
JAVA
: o comando "java" (uma máquina virtual Java). Evite isso e use uma regrajava_binary
sempre que possível. Pode ser um caminho relativo. Se você precisar mudar de diretório antes de invocarjava
, capture o diretório de trabalho antes de fazer a mudança. JAVABASE
: o diretório base que contém os utilitários Java. Pode ser um caminho relativo. Ele terá um subdiretório "bin".
Variáveis definidas pelo Starlark
Os criadores de regras e toolchain podem definir
variáveis totalmente personalizadas retornando um
provedor de
TemplateVariableInfo. Qualquer regra que dependa deles pelo atributo
toolchains
pode ler os valores: