Funções

Informar um problema Acessar o código-fonte

Conteúdo

pacote

package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)

Essa função declara metadados que se aplicam a todas as regras no pacote. Ele é usado no máximo uma vez em um pacote (arquivo BUILD).

Para a contraparte que declara metadados aplicados a todas as regras em todo o repositório, use a função repo() no arquivo REPO.bazel na raiz do seu 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 superior do arquivo, antes de qualquer regra.

Argumentos

Atributo Descrição
default_applicable_licenses

Alias para default_package_metadata.

default_visibility

Lista de rótulos. O padrão é [].

A visibilidade padrão das regras neste pacote.

Todas as regras deste pacote têm a visibilidade especificada no atributo, a menos que especificado de outra forma no atributo visibility da regra. Para informações detalhadas sobre a sintaxe desse atributo, consulte a documentação de visibilidade. A visibilidade padrão do pacote não se aplica a exports_files, que é público por padrão.

default_deprecation

String. O padrão é "".

Define a mensagem deprecation padrão para todas as regras neste pacote.

default_package_metadata

Lista de rótulos. O padrão é [].

Define uma lista padrão de destinos de metadados que se aplicam a todos os outros destinos no pacote. Geralmente, são destinos relacionados a declarações de licença e pacote OSS. Consulte rules_license para ver exemplos.

default_testonly

Booleano. O padrão é False, exceto conforme indicado

Define a propriedade testonly padrão para todas as regras no pacote.

Em pacotes abaixo de javatests, o valor padrão é True.

features

Strings de lista. O padrão é [].

Define várias sinalizações que afetam a semântica desse arquivo BUILD.

Esse recurso é usado principalmente pelas pessoas que trabalham no sistema de compilação para marcar pacotes que precisam de algum tipo de tratamento especial. Não use isso, a menos que explicitamente solicitado por alguém que esteja trabalhando no sistema de compilação.

Exemplos

A declaração abaixo declara que as regras nesse pacote são visíveis apenas para membros 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 nos atributos visibility.

Os grupos de pacotes são usados principalmente para controle de visibilidade. Um destino visível publicamente pode ser referenciado em todos os pacotes na árvore de origem. Um destino visível de modo privado só pode ser referenciado no próprio pacote, e não em subpacotes. Entre esses extremos, um destino pode permitir acesso ao próprio pacote e a qualquer um dos pacotes descritos por um ou mais grupos de pacotes. Para ver uma explicação mais detalhada sobre o sistema de visibilidade, consulte o atributo visibilidade.

Um determinado pacote faz parte do grupo se corresponder ao atributo packages ou se já estiver contido em um dos outros grupos de pacotes mencionados no atributo includes.

Os grupos de pacotes são tecnicamente direcionados, mas não são criados por regras e não têm nenhuma proteção de visibilidade.

Argumentos

Atributo Descrição
name

Nome (obrigatório)

Um nome exclusivo para o destino.

packages

Lista de strings. O padrão é [].

Uma lista de zero ou mais especificações de pacote.

Cada string de especificação do pacote pode ter um dos seguintes formatos:

  1. O nome completo de um pacote, sem o repositório dele, começando com uma barra dupla. Por exemplo, //foo/bar especifica o pacote que tem esse nome e que reside no mesmo repositório que o grupo de pacotes.
  2. Igual acima, mas com um /... à direita. Por exemplo, //foo/... especifica o conjunto de //foo e todos os respectivos subpacotes. //... especifica todos os pacotes no repositório atual.
  3. As strings public ou private, que especificam respectivamente cada pacote ou nenhum pacote. Neste formulário, é necessário definir a flag --incompatible_package_group_has_public_syntax.

Além disso, os dois primeiros tipos de especificações de pacote também podem ser prefixados com - para indicar que foram negados.

O grupo de pacotes contém qualquer pacote que corresponda a pelo menos uma das especificações positivas e nenhuma das especificações negativas. Por exemplo, o valor [//foo/..., -//foo/tests/...] inclui todos os subpacotes de //foo que não também são subpacotes de //foo/tests. O próprio //foo é incluído, enquanto //foo/tests não está.

Além da visibilidade pública, não há como especificar pacotes diretamente fora do repositório atual.

Se esse atributo estiver ausente, o processo será igual a defini-lo como uma lista vazia, o que também é o mesmo que defini-lo como uma lista que contém apenas private.

Observação:antes do Bazel 6.0, a especificação //... tinha um comportamento legado igual a public. Esse comportamento é corrigido quando --incompatible_fix_package_group_reporoot_syntax está ativado, que é o padrão após o Bazel 6.0.

Observação:antes do Bazel 6.0, quando esse atributo é serializado como parte de bazel query --output=proto (ou --output=xml), as barras iniciais são omitidas. Por exemplo, //pkg/foo/... será gerado como \"pkg/foo/...\". Esse comportamento é corrigido quando --incompatible_package_group_includes_double_slash está ativado, que é o padrão após o Bazel 6.0.

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 nos grupos de pacotes referenciados são levados para fazer parte desse grupo. É transitivo: se o grupo de pacotes a incluir o grupo de pacotes b e b incluir o grupo de pacotes c, todos os pacotes em c também serão membros de a.

Quando usado em conjunto com especificações de pacote negadas, observe que o conjunto de pacotes de cada grupo é calculado primeiro de maneira independente e os resultados são unidos. Isso significa que 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ó poderá se referir diretamente a arquivos de origem pertencentes a outro pacote se eles forem exportados explicitamente com uma instrução exports_files(). Leia mais sobre a visibilidade dos arquivos.

Como um comportamento legado, também os arquivos mencionados como entrada para uma regra 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 dele.

Argumentos

O argumento é uma lista de nomes de arquivos dentro do pacote atual. Também é possível especificar uma declaração de visibilidade. Nesse caso, os arquivos ficarão visíveis para os destinos especificados. 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 função package. 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 dos testes.

# from //test_data/BUILD

exports_files(["golden.txt"])

Globo

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 nova lista mutável e classificada dos caminhos deles. O Glob pesquisa apenas arquivos no próprio pacote e procura apenas arquivos de origem (não arquivos gerados nem outros destinos).

O identificador de um arquivo de origem será incluído no resultado se o caminho relativo ao pacote do arquivo corresponder a qualquer um dos padrões include e a nenhum dos exclude padrões.

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 no padrão são combinados com os segmentos do caminho. Os segmentos podem conter o caractere curinga *: isso corresponde a qualquer substring no segmento do caminho (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 autônomo.

Exemplos:
  • foo/bar.txt corresponde exatamente ao arquivo foo/bar.txt nesse pacote (a menos que foo/ seja um subpacote).
  • foo/*.txt corresponde a todos os arquivos no diretório foo/ se o arquivo terminar com .txt (a menos que foo/ seja um subpacote).
  • foo/a*.htm* corresponde a todos os arquivos no diretório foo/ que começa com a, depois tem uma string arbitrária (pode estar vazia), depois tem .htm e termina com outra string arbitrária (a menos que foo/ seja um subpacote), como foo/axx.htm e foo/a.html ou foo/axxx.html.
  • foo/* corresponde a todos os arquivos no diretório foo/, a menos que foo/ seja um subpacote. Ele não corresponde ao próprio diretório foo, mesmo que exclude_directories esteja definido como 0.
  • foo/** corresponde a todos os arquivos em todos os subdiretórios que não são subpacotes no subdiretório de primeiro nível do pacote foo/. Se exclude_directories estiver definido como 0, o próprio diretório foo também corresponderá ao padrão. Nesse caso, ** será considerado correspondente a segmentos de caminho zero
  • **/a.txt corresponde a arquivos a.txt no diretório desse pacote e em subdiretórios que não são subdiretórios.
  • **/bar/**/*.txt corresponderá a cada arquivo .txt em todos os subdiretórios que não são subpacotes desse pacote se pelo menos um diretório no caminho resultante tiver o nome bar, como xxx/bar/yyy/zzz/a.txt ou bar/a.txt (lembre-se de que ** também corresponde a zero segmentos) ou bar/zzz/a.txt
  • ** corresponde a todos os arquivos em todos os subdiretórios que não são subpacotes desse pacote.
  • foo**/a.txt é um padrão inválido, porque ** precisa ser um segmento
  • foo/ é um padrão inválido, porque o segundo segmento definido após / é uma string vazia

Se o argumento exclude_directories estiver ativado (definido como 1), os arquivos do diretório de tipos serão omitidos dos resultados (padrão 1).

Se o argumento allow_empty for definido como False, a função glob vai apresentar um erro se o resultado for a lista vazia.

Há várias limitações e ressalvas importantes:

  1. Como glob() é executado durante a avaliação do arquivo BUILD, glob() corresponde apenas aos arquivos na árvore de origem, nunca aos arquivos gerados. Se você estiver criando um destino que requer arquivos de origem e gerados, anexe uma lista explícita de arquivos gerados ao glob. Confira o exemplo abaixo com :mylib e :gen_java_srcs.

  2. Se uma regra tiver o mesmo nome de um arquivo de origem correspondente, a regra "sombreará" o arquivo.

    Para entender isso, lembre-se de que glob() retorna uma lista de caminhos. Portanto, usar glob() 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 houver também uma regra no pacote chamada "Foo.java" (que é permitida, embora o Bazel avise sobre isso), o consumidor do glob() vai usar a regra "Foo.java" (as saídas) em vez do arquivo "Foo.java". Consulte o problema 10395 do GitHub (em inglês) para saber mais.

  3. Os globs podem corresponder a arquivos em subdiretórios. Além disso, os nomes de subdiretórios podem ser caracteres curinga. No entanto...
  4. Os rótulos não podem cruzar o limite do pacote, e o glob não corresponde aos arquivos em subpacotes.

    Por exemplo, a expressão glob **/*.cc no pacote x não incluirá x/y/z.cc se x/y existir como um pacote (como x/y/BUILD ou em algum 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 incluiria x/y/z.cc se não houvesse nenhum pacote chamado x/y ou se ele fosse marcado como excluído usando a sinalização --deleted_packages.

  5. A restrição acima se aplica a todas as expressões glob, independentemente dos caracteres curinga que elas usam.
  6. Um arquivo oculto com o nome que começa com . é totalmente correspondido pelos caracteres curinga ** e *. Se você quiser corresponder um arquivo oculto com um padrão composto, seu padrão precisará começar com .. Por exemplo, * e .*.txt corresponderão a .foo.txt, mas *.txt não. Os diretórios ocultos são associados da mesma maneira. Eles podem incluir arquivos que não são necessários como entradas e podem aumentar o número de arquivos globos desnecessariamente e o consumo de memória. Para excluir diretórios ocultos, adicione-os ao argumento da lista "excluir".
  7. O caractere curinga "**" tem um caso de canto: 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 sob o diretório do pacote atual (mas, é claro, não indo para diretórios de subpacotes. Consulte a observação anterior sobre isso).

Em geral, tente fornecer uma extensão adequada (por exemplo, *.html) em vez de usar um "*" básico para um padrão glob. O nome mais explícito é autodocumentado e garante que você não corresponda acidentalmente a arquivos de backup ou arquivos emacs/vi/... salvos automaticamente.

Ao escrever regras de criação, é possível enumerar os elementos do glob. Isso permite gerar regras individuais para cada entrada, por exemplo. Consulte a seção exemplo de glob expandido abaixo.

Exemplos do Glob

Crie uma biblioteca Java compilada com base em todos os arquivos Java nesse diretório e em 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 nos 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 globos recursivos

Fazer o teste depender de todos os arquivos txt no diretório testdata e em qualquer um dos subdiretórios (e seus subdiretórios e assim por diante). Os subdiretórios que contêm um arquivo BUILD são ignorados. Veja as limitações e ressalvas acima.

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(["testdata/**/*.txt"]),
)

Crie uma biblioteca compilada com base em todos os arquivos Java nesse diretório e em 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 incrementabilidade do build e, portanto, aumentar os tempos de build.

java_library(
    name = "mylib",
    srcs = glob(
        ["**/*.java"],
        exclude = ["**/testing/**"],
    ),
)

Exemplos do globo expandido

Crie uma regra geral 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 ele contiver três arquivos correspondentes, a_test.cc, b_test.cc e c_test.cc, executando bazel query '//foo:all', todas as regras que foram geradas serão listadas:

$ 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. Portanto, o valor depende das sinalizações do Bazel na linha de comando. É possível usar isso, por exemplo, para definir dependências específicas da plataforma ou 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 os valores correspondentes. Cada condição é uma referência de rótulo a um config_setting ou constraint_value, que "corresponde" se a configuração do destino corresponder a um conjunto de valores esperado. O valor de mytarget#srcs se tornará a lista de rótulos que corresponder à 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 as mesmas sinalizações e valores de restrição que A, além de algumas sinalizações ou valores de restrição adicionais. Isso também significa que a resolução de especialização não foi projetada para criar uma ordenação, 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 falhará com um erro, a menos que todas as condições sejam resolvidas com o mesmo valor.
  • O pseudorótulo especial //conditions:default é considerado correspondente se nenhuma outra condição corresponde. Se essa condição for deixada de fora, alguma outra regra precisará corresponder para evitar um erro.
  • select pode ser incorporado dentro de uma atribuição de atributo maior. Portanto, srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...}) e srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]}) são expressões válidas.
  • select funciona com a maioria dos atributos, mas não todos. Atributos incompatíveis estão marcados como nonconfigurable na documentação.

    subpacotes

    subpackages(include, exclude=[], allow_empty=True)

    subpackages() é uma função auxiliar, semelhante a glob(), que lista subpacotes em vez de arquivos e diretórios. Ele usa os mesmos padrões de caminho que glob() e pode corresponder a qualquer subpacote que seja um descendente direto do arquivo BUILD que está sendo carregado no momento. 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á na ordem de classificação e contém caminhos relativos ao pacote de carregamento atual que correspondem aos padrões fornecidos em include, e não aos de exclude.

    Exemplo

    O exemplo a seguir lista todos os subpacotes diretos para o pacote foo/BUILD

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/bar/but/bad/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs1 = subpackages(include = ["**"])
    
    # results in subs1 == ["sub", "bar/baz", "bar/but/bad"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    
    subs2 = subpackages(include = ["bar/*"])
    # results in subs2 = ["bar/baz"]
    #
    # Since 'bar' is not a subpackage itself, this looks for any subpackages under
    # all first level subdirectories of 'bar'.
    
    subs3 = subpackages(include = ["bar/**"])
    # results in subs3 = ["bar/baz", "bar/but/bad"]
    #
    # Since bar is not a subpackage itself, this looks for any subpackages which are
    # (1) under all subdirectories of 'bar' which can be at any level, (2) not a
    # subpackage of another subpackages.
    
    subs4 = subpackages(include = ["sub"])
    subs5 = subpackages(include = ["sub/*"])
    subs6 = subpackages(include = ["sub/**"])
    # results in subs4 and subs6 being ["sub"]
    # results in subs5 = [].
    #
    # In subs4, expression "sub" checks whether 'foo/sub' is a package (i.e. is a
    # subpackage of 'foo').
    # In subs5, "sub/*" looks for subpackages under directory 'foo/sub'. Since
    # 'foo/sub' is already a subpackage itself, the subdirectories will not be
    # traversed anymore.
    # In subs6, 'foo/sub' is a subpackage itself and matches pattern "sub/**", so it
    # is returned. But the subdirectories of 'foo/sub' will not be traversed
    # anymore.
    
    .

    Em geral, é preferível que, em vez de chamar essa função diretamente, os usuários usem o módulo "subpackages" de skylib.