- Usar
- Variáveis predefinidas
- Variáveis genrule predefinidas
- 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 de 'Variável de marca'".
Eles podem ser usados, por exemplo, para injetar caminhos específicos de cadeia de ferramentas em ações de build criadas pelo usuário.
O Bazel oferece variáveis predefinidas, que estão disponíveis para todas as metas, e variáveis personalizadas, que são definidas em metas de dependência e estão disponíveis apenas para metas 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
Os atributos marcados como "Sujeito à substituição 'Criar variável'" podem
fazer referência à variável "Marca" FOO
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 será:
my_attr = "prefix bar suffix"
Se FOO
não corresponder a uma variável conhecida pelo destino
de consumo, o Bazel vai falhar com um erro.
Variáveis "Make" com nomes que não são símbolos de letras, como @
, também podem ser referenciadas usando apenas um cifrão, sem os parênteses. Exemplo:
my_attr = "prefix $@ suffix"
Para escrever $
como um literal de string (ou seja, para evitar a expansão de variáveis), escreva $$
.
Variáveis predefinidas
As variáveis predefinidas "Marca" podem ser referenciadas por qualquer atributo marcado como "Sujeito à substituição de 'Variável de marca'" em qualquer destino.
Para conferir a lista dessas variáveis e os valores delas para um determinado conjunto de opções de build, execute
bazel info --show_make_env [build options]
e observe as linhas de saída na parte de cima com letras maiúsculas.
Confira um exemplo de variáveis predefinidas.
Variáveis de opção da cadeia de ferramentas
COMPILATION_MODE
:fastbuild
,dbg
ouopt
. (mais detalhes)
Variáveis de caminho
-
BINDIR
: a base da árvore binária gerada para a arquitetura de destino.Uma árvore diferente pode ser usada para programas executados durante a compilação na arquitetura do host, para oferecer suporte à compilação cruzada.
Se você quiser executar uma ferramenta em um
genrule
, a maneira recomendada de acessar o caminho dela é$(execpath toolname)
, em que toolname precisa estar listado no atributotools
dogenrule
. GENDIR
: A base da árvore de código gerada para a arquitetura de destino.
Variáveis de arquitetura da máquina
-
TARGET_CPU
: A CPU da arquitetura de destino, por exemplo,k8
.
Variáveis genrule predefinidas
Os seguintes estão disponíveis especialmente para o atributo cmd
de genrule
e são geralmente importantes para que esse atributo funcione.
Confira um exemplo de variáveis genrule predefinidas.
OUTS
: a lista deouts
dogenrule
. Se você tiver apenas um arquivo de saída, também poderá usar$@
.-
SRCS
: a listasrcs
degenrule
(ou, mais precisamente, os nomes de caminho dos arquivos correspondentes aos rótulos na listasrcs
). Se você tiver apenas um arquivo de origem, também poderá usar$<
. -
<
:SRCS
, se for um único arquivo. Caso contrário, um erro de build será acionado. -
@
:OUTS
, se for um único arquivo. Caso contrário, um erro de build será acionado. -
RULEDIR
: o diretório de saída do destino, ou seja, o diretório correspondente ao nome do pacote que contém o destino na árvoregenfiles
oubin
. Para//my/pkg:my_genrule
, isso sempre termina emmy/pkg
, mesmo que as saídas de//my/pkg:my_genrule
estejam em subdiretórios. -
@D
: o diretório de saída. Se outs tiver uma entrada, ela será expandida para o diretório que contém esse arquivo. Se ele tiver várias entradas, isso será expandido para o diretório raiz do pacote na árvoregenfiles
, mesmo que todos os arquivos de saída estejam no mesmo subdiretório.Observação:use
RULEDIR
em vez de@D
porqueRULEDIR
tem uma semântica mais simples e se comporta da mesma forma, independente do número de arquivos de saída.Se a genrule precisar gerar arquivos intermediários temporários (talvez como resultado do uso de alguma outra ferramenta, como um compilador), ela vai tentar gravar em
@D
(embora/tmp
também possa ser gravado) e remover esses arquivos antes de terminar.Evite gravar em diretórios que contenham entradas. Eles podem estar em sistemas de arquivos somente leitura. Mesmo que não seja, isso vai descartar a árvore de origem.
Variáveis predefinidas de caminho de origem/saída
As variáveis predefinidas execpath
, execpaths
, rootpath
, rootpaths
, location
e locations
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 de arquivos de saída abaixo).
Confira um exemplo de variáveis de caminho predefinidas.
-
execpath
: indica 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 seu espaço de trabalho. O arquivo de origemempty.source
está vinculado ao 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 preparados 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
. Assim, o arquivo de saídaapp
é gravado embazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/app
. Portanto, o caminho de execução ébazel-out/cpu-opt-exec-hash/bin/testapp/app
. Esse prefixo extra permite criar o mesmo destino para, por exemplo, duas CPUs diferentes no mesmo build sem que os resultados se substituam.O rótulo transmitido a 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 for "false" ou se o rótulo estiver malformado, a build vai falhar com um erro.
-
rootpath
: indica o caminho que um binário criado pode usar para encontrar uma dependência no tempo de execução em relação ao subdiretório do diretório runfiles correspondente ao repositório principal. Observação:isso só funciona se--enable_runfiles
estiver ativado, o que não acontece no Windows por padrão. Userlocationpath
para suporte multiplataforma.Isso é semelhante a
execpath
, mas remove os prefixos de configuração descritos acima. No exemplo acima, isso significa queempty.source
eapp
usam caminhos puros relativos ao espaço de trabalho:testapp/empty.source
etestapp/app
.O
rootpath
de um arquivo em um repositório externorepo
começa com../repo/
, seguido pelo caminho relativo ao repositório.Isso 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 em tempo de execução, seja 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 difere 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
começa comrepo/
, seguido pelo caminho relativo ao repositório.Transmitir esse caminho para um binário e resolvê-lo para um caminho do sistema de arquivos usando as bibliotecas de runfiles é a abordagem preferida para encontrar dependências no ambiente de execução. Em comparação com
rootpath
, ele tem a vantagem de funcionar em todas as plataformas, mesmo que o diretório de runfiles não esteja disponível.Isso 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 pré-Starlark e não é recomendado, a menos que você saiba o que ele faz em uma regra específica. Consulte #2475 para mais detalhes.
execpaths
, rootpaths
, rlocationpaths
e locations
são as variações no plural de execpath
, rootpath
, rlocationpaths
e location
, respectivamente. Eles aceitam 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 geram erros de build.
Todos os rótulos referenciados precisam aparecer nos arquivos srcs
e de saída ou em deps
do destino de consumo. Caso contrário, a criação falha. Os destinos em C++ também podem referenciar rótulos em data
.
Os rótulos não precisam estar no formato canônico: foo
, :foo
e //somepkg:foo
são aceitos.
Variáveis personalizadas
As variáveis personalizadas de "Marca" podem ser referenciadas por qualquer atributo marcado como "Sujeito à substituição da variável 'Marca'", mas apenas em destinos que dependem de outros destinos que definem essas variáveis.
Como prática recomendada, todas as variáveis precisam ser personalizadas, a menos que haja um bom motivo para incorporá-las ao Bazel principal. Isso evita que o Bazel precise carregar dependências potencialmente caras para fornecer variáveis que os consumidores de tarets podem não se importar.
Variáveis da cadeia de ferramentas do C++
Os seguintes itens são definidos nas regras da cadeia de ferramentas do C++ e estão disponíveis para qualquer regra
que defina toolchains =
["@bazel_tools//tools/cpp:current_cc_toolchain"]
Algumas regras, como java_binary
, incluem implicitamente
a cadeia de ferramentas do C++ na definição delas. Elas herdam essas variáveis automaticamente.
As regras integradas do C++ são muito mais sofisticadas do que "execute 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, além de testes de execução rápida em várias plataformas, as regras integradas fazem o possível para garantir que as entradas, saídas e flags de linha de comando corretas sejam definidas em cada uma das várias ações geradas internamente.
Essas variáveis são um mecanismo de substituição usado por especialistas em idiomas em casos raros. Se você quiser 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
: O identificador do compilador C/C++, por exemplo,llvm
. -
CC
: o comando do compilador C e C++.Recomendamos sempre usar
CC_FLAGS
em combinação comCC
. Se não fizer isso, você assume os riscos. CC_FLAGS
: um conjunto mínimo de flags para que o compilador C/C++ possa ser usado por genrules. Em particular, isso contém flags para selecionar a arquitetura correta seCC
for compatível com várias arquiteturas.-
NM
: o comando "nm" do crosstool. -
OBJCOPY
: o comando objcopy do mesmo pacote do compilador C/C++. -
STRIP
: o comando strip do mesmo conjunto do compilador C/C++.
Variáveis da cadeia de ferramentas Java
Os seguintes itens são definidos em regras de cadeia de ferramentas Java e estão disponíveis para qualquer regra
que defina toolchains =
["@bazel_tools//tools/jdk:current_java_runtime"]
(ou
"@bazel_tools//tools/jdk:current_host_java_runtime"
para o equivalente da cadeia de ferramentas do host).
A maioria das ferramentas no JDK não deve ser usada diretamente. As regras integradas do Java usam abordagens muito mais sofisticadas para compilação e empacotamento do Java do que as ferramentas upstream podem expressar, como Jars de interface, Jars de interface de cabeçalho e implementações de empacotamento e fusão de Jar altamente otimizadas.
Essas variáveis são um mecanismo de substituição usado por especialistas em idiomas em casos raros. Se você quiser 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 em Starlark
Os gravadores de regras e toolchain podem definir variáveis completamente personalizadas retornando um provedor TemplateVariableInfo. Qualquer regra que dependa desses valores pelo atributo
toolchains
pode ler os valores: