Índice
Pacote
package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)
Essa função declara metadados que se aplicam a todas as regras do pacote. Ela é usada no máximo uma vez em um pacote (arquivo BUILD).
Para a contrapartida que declara metadados aplicáveis a todas as regras de todo o
repositório, use a função repo() no arquivo
REPO.bazel na raiz do repositório.
A função repo() usa exatamente os mesmos argumentos que package().
A função package() precisa ser chamada logo após todas as instruções load() na parte de cima do arquivo, antes de qualquer regra.
Argumentos
| Atributo | Descrição |
|---|---|
default_applicable_licenses |
Alias para |
default_visibility |
Lista de rótulos; o padrão é A visibilidade padrão das regras neste pacote. Cada regra neste pacote tem a visibilidade especificada neste
atributo, a menos que seja especificado de outra forma no |
default_deprecation |
String; o padrão é Define a mensagem
|
default_package_metadata |
Lista de rótulos; o padrão é Define uma lista padrão de metas de metadados que se aplicam a todas as outras metas no pacote. Essas são normalmente metas relacionadas a declarações de pacotes e licenças de OSS. Consulte rules_license para exemplos. |
default_testonly |
Booleano; o padrão é Define a propriedade
Em pacotes em |
features |
Lista de strings; o padrão é Define várias flags que afetam a semântica desse arquivo BUILD. Esse recurso é usado principalmente pelas pessoas que trabalham no sistema de build para marcar pacotes que precisam de algum tipo de tratamento especial. Não use isso, a menos que seja solicitado explicitamente por alguém que trabalhe no sistema de build. |
Exemplos
A declaração abaixo declara que as regras neste pacote são visíveis apenas para participantes do grupo de pacotes//foo:target. As declarações de visibilidade individuais em uma regra, se presentes, substituem essa especificação.
package(default_visibility = ["//foo:target"])
package_group
package_group(name, packages, includes)
Essa função define um conjunto de pacotes
e associa um rótulo ao conjunto. O rótulo pode ser referenciado em atributos visibility.
Os grupos de pacotes são usados principalmente para controle de visibilidade. Uma meta visível publicamente pode ser referenciada em todos os pacotes na árvore de origem. Uma meta visível de forma particular só pode ser referenciada no próprio pacote (não em subpacotes). Entre esses extremos, uma meta pode permitir o acesso ao próprio pacote e a qualquer um dos pacotes descritos por um ou mais grupos de pacotes. Para uma explicação mais detalhada do sistema de visibilidade, consulte o atributo de visibilidade.
Um determinado pacote é considerado no grupo se corresponder ao atributo packages ou já estiver contido em um dos outros grupos de pacotes mencionados no atributo includes.
Os grupos de pacotes são tecnicamente metas, mas não são criados por regras e não têm proteção de visibilidade.
Argumentos
| Atributo | Descrição |
|---|---|
name |
Nome; obrigatório Um nome exclusivo para esse destino. |
packages |
Lista de strings; o padrão é Uma lista de zero ou mais especificações de pacote. Cada string de especificação de pacote pode ter uma das seguintes formas:
Além disso, os dois primeiros tipos de especificações de pacote também podem
ter o prefixo O grupo de pacotes contém qualquer pacote que corresponda a pelo menos uma de
suas especificações positivas e nenhuma de suas especificações negativas.
Por exemplo, o valor Além da visibilidade pública, não há como especificar diretamente pacotes fora do repositório atual. Se esse atributo estiver ausente, será o mesmo que defini-lo como uma
lista vazia, que também é o mesmo que defini-lo como uma lista que contém
apenas Observação:antes do Bazel 6.0, a especificação Observação: antes do Bazel 6.0, quando esse atributo era serializado como
parte de |
includes |
Lista de rótulos; o padrão é Outros grupos de pacotes incluídos neste. Os rótulos nesse atributo precisam se referir a outros grupos de pacotes.
Os pacotes em grupos de pacotes referenciados são considerados parte desse
grupo de pacotes. Isso é transitivo: se o grupo de pacotes
Quando usado com especificações de pacote negadas, observe que o conjunto de pacotes para cada grupo é calculado primeiro de forma independente e os resultados são unidos. Isso significa que as especificações negadas em um grupo não têm efeito nas especificações em outro grupo. |
Exemplos
A declaração package_group a seguir especifica um grupo de pacotes chamado "tropical" que contém frutas tropicais.
package_group(
name = "tropical",
packages = [
"//fruits/mango",
"//fruits/orange",
"//fruits/papaya/...",
],
)
As declarações a seguir especificam os grupos de pacotes de um aplicativo fictício:
package_group(
name = "fooapp",
includes = [
":controller",
":model",
":view",
],
)
package_group(
name = "model",
packages = ["//fooapp/database"],
)
package_group(
name = "view",
packages = [
"//fooapp/swingui",
"//fooapp/webui",
],
)
package_group(
name = "controller",
packages = ["//fooapp/algorithm"],
)
exports_files
exports_files([label, ...], visibility, licenses)
exports_files() especifica uma lista de arquivos pertencentes a
esse pacote que são exportados para outros pacotes.
O arquivo BUILD de um pacote só pode se referir diretamente a arquivos de origem pertencentes
a outro pacote se eles forem exportados explicitamente com uma
exports_files() instrução. Saiba mais sobre
a visibilidade dos arquivos.
Como um comportamento legado, os arquivos mencionados como entrada para uma regra também são exportados
com a visibilidade padrão até que a flag
--incompatible_no_implicit_file_export
seja invertida. No entanto, não confie nesse comportamento e migre ativamente.
Argumentos
O argumento é uma lista de nomes de arquivos no pacote atual. Uma
declaração de visibilidade também pode ser especificada. Nesse caso, os arquivos ficarão
visíveis para as metas especificadas. Se nenhuma visibilidade for especificada, os arquivos
ficarão visíveis para todos os pacotes, mesmo que uma visibilidade padrão do pacote tenha sido
especificada na package
função. As licenças
também podem ser especificadas.
Exemplo
O exemplo a seguir exporta golden.txt, um arquivo de texto do pacote test_data, para que outros pacotes possam usá-lo, por exemplo, no atributo data de testes.
# from //test_data/BUILD exports_files(["golden.txt"])
glob
glob(include, exclude=[], exclude_directories=1, allow_empty=True)
Glob é uma função auxiliar que encontra todos os arquivos que correspondem a determinados padrões de caminho e retorna uma lista nova, mutável e classificada dos caminhos. O Glob só pesquisa arquivos no próprio pacote e procura apenas arquivos de origem (não arquivos gerados nem outras metas).
O rótulo de um arquivo de origem é incluído no resultado se o caminho relativo ao pacote do arquivo corresponder a qualquer um dos padrões include e a nenhum dos padrões exclude.
As listas include e exclude contêm padrões de caminho relativos ao pacote atual. Cada padrão pode consistir em um ou mais segmentos de caminho. Como de costume com caminhos Unix, esses segmentos são separados por /. Os segmentos podem conter o caractere curinga *: ele corresponde a
qualquer substring no segmento de caminho (até mesmo a substring vazia), excluindo o
separador de diretório /. Esse caractere curinga pode ser usado várias vezes em um segmento de caminho. Além disso, o caractere curinga ** pode corresponder a zero ou mais segmentos de caminho completos, mas precisa ser declarado como um segmento de caminho independente.
foo/bar.txtcorresponde exatamente ao arquivofoo/bar.txtneste pacotefoo/*.txtcorresponde a todos os arquivos no diretóriofoo/se o arquivo terminar com.txt(a menos quefoo/seja um subpacote)foo/a*.htm*corresponde a todos os arquivos no diretóriofoo/que começam coma, têm uma string arbitrária (pode estar vazia), têm.htme terminam com outra string arbitrária, comofoo/axx.htmefoo/a.htmloufoo/axxx.html**/a.txtcorresponde a todos os arquivosa.txtem todos os subdiretórios desse pacote**/bar/**/*.txtcorresponde a todos os arquivos.txtem todos os subdiretórios desse pacote, se pelo menos um diretório no caminho resultante for chamadobar, comoxxx/bar/yyy/zzz/a.txtoubar/a.txt(lembre-se de que**também corresponde a zero segmentos) oubar/zzz/a.txt**corresponde a todos os arquivos em todos os subdiretórios desse pacotefoo**/a.txté um padrão inválido, porque**precisa ficar sozinho como um segmento
Se o argumento exclude_directories estiver ativado (definido como 1), os arquivos do tipo diretório serão omitidos dos resultados (padrão 1).
Se o argumento allow_empty estiver definido como False, a função glob vai gerar um erro se o resultado for a lista vazia.
Há várias limitações e ressalvas importantes:
-
Como
glob()é executado durante a avaliação do arquivo BUILD,glob()corresponde a arquivos apenas na árvore de origem, nunca arquivos gerados. Se você estiver criando uma meta que exige arquivos de origem e gerados, anexe uma lista explícita de arquivos gerados ao glob. Consulte o exemplo abaixo com:mylibe:gen_java_srcs. -
Se uma regra tiver o mesmo nome de um arquivo de origem correspondente, a regra vai "sombrear" o arquivo.
Para entender isso, lembre-se de que
glob()retorna uma lista de caminhos. Portanto, usarglob()no atributo de outras regras (por exemplo,srcs = glob(["*.cc"])) tem o mesmo efeito que listar os caminhos correspondentes explicitamente. Se, por exemplo,glob()gerar["Foo.java", "bar/Baz.java"]mas também houver uma regra no pacote chamado "Foo.java" (que é permitida, embora o Bazel avise sobre ela), o consumidor doglob()vai usar a regra "Foo.java" (as saídas dela) em vez do arquivo "Foo.java". Consulte o problema 10395 do GitHub (link em inglês) para mais detalhes. - Os globs podem corresponder a arquivos em subdiretórios. E os nomes dos subdiretórios podem ser curingas. No entanto...
-
Os rótulos não podem cruzar o limite do pacote, e o glob não corresponde a arquivos em subpacotes.
Por exemplo, a expressão glob
**/*.ccno pacotexnão incluix/y/z.ccsex/yexistir como um pacote (comox/y/BUILD, ou em outro lugar no caminho do pacote). Isso significa que o resultado da expressão glob depende da existência de arquivos BUILD. Ou seja, a mesma expressão glob incluiriax/y/z.ccse não houvesse um pacote chamadox/you se ele fosse marcado como excluído usando a --deleted_packages flag. - A restrição acima se aplica a todas as expressões glob, independentemente dos caracteres curinga usados.
-
Um arquivo oculto com nome de arquivo começando com
.é totalmente correspondido por ambos os caracteres curinga**e*. Se você quiser corresponder um arquivo oculto com um padrão composto, o padrão precisa começar com um.. Por exemplo,*e.*.txtvão corresponder a.foo.txt, mas*.txtnão. Os diretórios ocultos também são correspondidos da mesma maneira. Os diretórios ocultos podem incluir arquivos que não são necessários como entradas e podem aumentar o número de arquivos globados desnecessariamente e o consumo de memória. Para excluir diretórios ocultos, adicione-os ao argumento da lista "exclude". -
O caractere curinga "**" tem um caso extremo: o padrão
"**"não corresponde ao caminho do diretório do pacote. Ou seja,glob(["**"], exclude_directories = 0)corresponde a todos os arquivos e diretórios transitivamente estritamente no diretório do pacote atual (mas, é claro, não entrando em diretórios de subpacotes. Consulte a observação anterior sobre isso).
Em geral, tente fornecer uma extensão apropriada (por exemplo, *.html) em vez de usar um '*' simples para um padrão glob. O nome mais explícito é autoexplicativo e garante que você não corresponda acidentalmente a arquivos de backup ou arquivos de salvamento automático do emacs/vi/....
Ao escrever regras de build, é possível enumerar os elementos do glob. Isso permite gerar regras individuais para cada entrada, por exemplo. Consulte a seção de exemplo de glob expandido abaixo.
Exemplos de glob
Crie uma biblioteca Java criada com todos os arquivos Java neste diretório e todos os arquivos gerados pela regra :gen_java_srcs.
java_library(
name = "mylib",
srcs = glob(["*.java"]) + [":gen_java_srcs"],
deps = "...",
)
genrule(
name = "gen_java_srcs",
outs = [
"Foo.java",
"Bar.java",
],
...
)
Inclua todos os arquivos txt no diretório testdata, exceto experimental.txt. Os arquivos em subdiretórios de testdata não serão incluídos. Se você quiser que esses arquivos sejam incluídos, use um glob recursivo (**).
sh_test(
name = "mytest",
srcs = ["mytest.sh"],
data = glob(
["testdata/*.txt"],
exclude = ["testdata/experimental.txt"],
),
)
Exemplos de glob recursivo
Faça com que o teste dependa de todos os arquivos txt no diretório testdata e em qualquer um dos subdiretórios (e subdiretórios deles e assim por diante). Os subdiretórios que contêm um arquivo BUILD são ignorados. (Consulte as limitações e ressalvas acima.)
sh_test(
name = "mytest",
srcs = ["mytest.sh"],
data = glob(["testdata/**/*.txt"]),
)
Crie uma biblioteca criada com todos os arquivos Java neste diretório e todos os subdiretórios, exceto aqueles cujo caminho inclui um diretório chamado testing. Esse padrão precisa ser evitado, se possível, porque pode reduzir a incrementalidade do build e, portanto, aumentar os tempos de build.
java_library(
name = "mylib",
srcs = glob(
["**/*.java"],
exclude = ["**/testing/**"],
),
)
Exemplos de glob expandido
Crie uma genrule individual para *_test.cc no diretório atual que conte o número de linhas no arquivo.
# Conveniently, the build language supports list comprehensions.
[genrule(
name = "count_lines_" + f[:-3], # strip ".cc"
srcs = [f],
outs = ["%s-linecount.txt" % f[:-3]],
cmd = "wc -l $< >$@",
) for f in glob(["*_test.cc"])]
Se o arquivo BUILD acima estiver no pacote //foo e o pacote contiver três arquivos correspondentes, a_test.cc, b_test.cc e c_test.cc, a execução de bazel query '//foo:all' vai listar todas as regras geradas:
$ bazel query '//foo:all' | sort //foo:count_lines_a_test //foo:count_lines_b_test //foo:count_lines_c_test
select
select(
{conditionA: valuesA, conditionB: valuesB, ...},
no_match_error = "custom message"
)
select() é a função auxiliar que torna um atributo de regra
configurável.
Ele pode substituir o lado direito de
quase
qualquer atribuição de atributo para que o valor dependa das flags do Bazel da linha de comando.
Você pode usar isso, por exemplo, para definir dependências específicas da plataforma ou para
incorporar recursos diferentes, dependendo se uma regra é criada no modo "desenvolvedor"
ou "lançamento".
O uso básico é o seguinte:
sh_binary(
name = "mytarget",
srcs = select({
":conditionA": ["mytarget_a.sh"],
":conditionB": ["mytarget_b.sh"],
"//conditions:default": ["mytarget_default.sh"]
})
)
Isso torna o atributo srcs de
um sh_binary configurável, substituindo a atribuição normal da lista de rótulos
por uma chamada select que mapeia
as condições de configuração para valores correspondentes. Cada condição é uma referência de rótulo a um config_setting ou constraint_value, que "corresponde" se a configuração da meta corresponder a um conjunto esperado de valores. O valor de mytarget#srcs se torna a lista de rótulos que corresponde à invocação atual.
Observações:
- Exatamente uma condição é selecionada em qualquer invocação.
- Se várias condições corresponderem e uma for uma especialização das outras, a especialização terá precedência. A condição B é considerada uma especialização da condição A se B tiver todas as mesmas flags e valores de restrição que A, além de algumas flags ou valores de restrição adicionais. Isso também significa que a resolução de especialização não foi projetada para criar uma ordem, conforme demonstrado no exemplo 2 abaixo.
- Se várias condições corresponderem e uma não for uma especialização de todas as outras, o Bazel vai falhar com um erro, a menos que todas as condições sejam resolvidas para o mesmo valor.
- O pseudorrótulo especial
//conditions:defaulté considerado uma correspondência se nenhuma outra condição corresponder. Se essa condição for omitida, alguma outra regra precisará corresponder para evitar um erro. selectpode ser incorporado dentro de uma atribuição de atributo maior. Portanto,srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...})esrcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]})são expressões válidas.selectfunciona com a maioria, mas não com todos os atributos. Os atributos incompatíveis são marcados comononconfigurablena documentação.subpackages
subpackages(include, exclude=[], allow_empty=True)
subpackages()é uma função auxiliar, semelhante aglob(), que lista subpacotes em vez de arquivos e diretórios. Ela usa os mesmos padrões de caminho queglob()e pode corresponder a qualquer subpacote que é um descendente direto do arquivo BUILD que está sendo carregado. Consulte glob para uma explicação detalhada e exemplos de padrões de inclusão e exclusão.A lista resultante de subpacotes retornados está em ordem classificada e contém caminhos relativos ao pacote de carregamento atual que correspondem aos padrões fornecidos em
includee não aos deexclude.Exemplo
O exemplo a seguir lista todos os subpacotes diretos do pacote
foo/BUILD# The following BUILD files exist: # foo/BUILD # foo/bar/baz/BUILD # foo/sub/BUILD # foo/sub/deeper/BUILD # # In foo/BUILD a call to subs = subpackages(include = ["**"]) # results in subs == ["sub", "bar/baz"] # # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of # 'foo'
Em geral, é preferível que, em vez de chamar essa função diretamente que os usuários usem o módulo 'subpackages' do skylib.