Esta página se concentra em escrever regras compatíveis com o Windows, problemas comuns de escrever regras portáteis e algumas soluções.
Caminhos
Problemas:
Limite de tamanho: o caminho pode ter até 259 caracteres.
Embora o Windows também suporte caminhos mais longos (até 32.767 caracteres), muitos programas são criados com o limite mínimo.
Esteja ciente disso sobre os programas que você executa nas ações.
Diretório de trabalho: também é limitado a 259 caracteres.
Os processos não podem usar
cd
em um diretório com mais de 259 caracteres.Diferenciação entre maiúsculas e minúsculas: os caminhos do Windows são indiferentes a maiúsculas e os caminhos Unix.
Lembre-se disso ao criar linhas de comando para ações.
Separadores de caminho: são uma barra invertida (
\`), not forward slash (
/`).O Bazel armazena caminhos no estilo Unix com separadores
/
. Alguns programas do Windows têm suporte para Caminhos no estilo Unix, outros não. Alguns comandos integrados no cmd.exe oferecem suporte a eles, outros não.É melhor sempre usar
\` separators on Windows: replace
/with
` ao criar um comando linhas e variáveis de ambiente para ações.Caminhos absolutos: não começam com uma barra (
/
).Os caminhos absolutos no Windows começam com uma letra de unidade, como
C:\foo\bar.txt
. Não há raiz do sistema de arquivos.Lembre-se disso caso sua regra verifique se um caminho é absoluto. Caminhos absolutos devem ser evitados, já que muitas vezes eles não são portáteis.
Soluções:
Mantenha os caminhos curtos.
Evite nomes longos de diretórios, estruturas de diretórios profundamente aninhadas, nomes de arquivos longos, espaços de trabalho longos nomes longos, nomes de alvos longos.
Tudo isso pode se tornar um componente de caminho das ações arquivos de entrada e pode esgotar o tamanho do caminho ou ao atingir um limite estabelecido.
Use uma raiz de saída curta.
Use a flag
--output_user_root=<path>
para especificar um caminho curto para as saídas do Bazel. Uma boa ideia é ter uma unidade (ou unidade virtual) apenas para saídas do Bazel (como o arquivoD:\`), and adding this line to your
.bazelrc`:build --output_user_root=D:/
ou
build --output_user_root=C:/_bzl
Use cruzamentos.
Em geral, as junções são[1] links simbólicos de diretório. É fácil criar junções e podem apontar para diretórios (no mesmo computador) com caminhos longos. Se uma ação de versão cria um em uma junção com caminho curto, mas com destino longo, as ferramentas com limite de caminho curto podem acessar os arquivos no diretório em junção.
Em arquivos
.bat
ou em cmd.exe, você pode criar junções como:mklink /J c:\path\to\junction c:\path\to\very\long\target\path
[1]: estritamente As junções não são links simbólicos, mas para as ações de compilação, você pode considerar junções como links simbólicos de diretório.
Substitua
/
por `` em caminhos em actions / envvars.Ao criar a linha de comando ou as variáveis de ambiente para uma ação, torne os caminhos Estilo Windows. Exemplo:
def as_path(p, is_windows): if is_windows: return p.replace("/", "\\") else: return p
Variáveis de ambiente
Problemas:
Diferenciação entre letras maiúsculas e minúsculas: os nomes das variáveis de ambiente do Windows não diferenciam maiúsculas de minúsculas.
Por exemplo, em Java,
System.getenv("SystemRoot")
eSystem.getenv("SYSTEMROOT")
produzem o mesmo resultado. Isso também se aplica a outros idiomas.Hermeticity: as ações precisam usar o menor número possível de variáveis de ambiente personalizadas.
As variáveis de ambiente fazem parte da chave de cache da ação. Se uma ação usar variáveis de ambiente que mudam com frequência ou que são personalizados para os usuários, o que torna a regra menos armazenável em cache.
Soluções:
Use apenas nomes de variáveis de ambiente em maiúsculas.
Esse recurso funciona no Windows, macOS e Linux.
Minimize ambientes de ação.
Ao usar
ctx.actions.run
, defina o ambiente comoctx.configuration.default_shell_env
. Se o precisa de mais variáveis de ambiente. Coloque-as em um dicionário e passe-as para a ação. Exemplo:load("@bazel_skylib//lib:dicts.bzl", "dicts") def _make_env(ctx, output_file, is_windows): out_path = output_file.path if is_windows: out_path = out_path.replace("/", "\\") return dicts.add(ctx.configuration.default_shell_env, {"MY_OUTPUT": out_path})
Ações
Problemas:
Saídas executáveis: todo arquivo executável precisa ter uma extensão executável.
As extensões mais comuns são
.exe
(arquivos binários) e.bat
(scripts em lote).Saiba que os scripts de shell (
.sh
) NÃO são executáveis no Windows. não é possível especificá-las comoexecutable
dectx.actions.run
. Os arquivos também não podem ter a permissão+x
. Por isso, e não executa arquivos arbitrários como no Linux.Comandos Bash: por questão de portabilidade, evite executar comandos Bash diretamente nas ações.
O Bash é muito usado em sistemas do tipo Unix, mas geralmente não está disponível no Windows. O Bazel é confiando cada vez mais no Bash (MSYS2), então é menos provável que os futuros usuários tenham o MSYS2. instalado junto com o Bazel. Para facilitar o uso de regras no Windows, evite executar comandos Bash no ações.
Terminações de linha: o Windows usa CRLF (
\r\n
), e sistemas Unix usam LF (\n
).Esteja ciente disso ao comparar arquivos de texto. Preste atenção às configurações do Git, principalmente de linhas finais ao finalizar a compra ou fazer a confirmação. Consulte a configuração
core.autocrlf
do Git.
Soluções:
Use uma regra específica sem Bash.
native.genrule()
é um wrapper para comandos Bash e geralmente é usado para resolver problemas simples. como copiar um arquivo ou gravar um arquivo de texto. Você pode evitar confiar no Bash (e reinventar o wheel): veja se o bazel-skylib tem uma regra específica para suas necessidades. Nenhuma delas depende do Bash quando criados/testados no Windows.Exemplos de regras de criação:
copy_file()
(fonte, documentação): copia um arquivo para outro lugar, tornando-o executável opcionalmentewrite_file()
(fonte, documentação): grava um arquivo de texto com as terminações de linha desejadas (auto
,unix
ouwindows
), opcionalmente torná-lo executável (se for um script)run_binary()
(fonte, documentação): executa um binário (ou regra*_binary
) com determinadas entradas e saídas esperadas como uma ação de build (este é um wrapper de regra de criação paractx.actions.run
)native_binary()
(fonte, documentação): envolve um binário nativo em uma regra*_binary
, que você pode usarbazel run
ou usar na classerun_binary()
Atributotool
outools
denative.genrule()
Exemplos de regra de teste:
diff_test()
(fonte, documentação): que compara o conteúdo de dois arquivosnative_test()
(fonte, documentação): envolve um binário nativo em uma regra*_test
, que você podebazel test
No Windows, use scripts
.bat
para coisas triviais.Em vez de scripts
.sh
, é possível resolver tarefas triviais com scripts.bat
.Por exemplo, se você precisar de um script que não faz nada, exibe uma mensagem ou sai com uma um arquivo
.bat
simples será suficiente. Se a regra retornarDefaultInfo()
provedor, o campoexecutable
poderá se referir a esse arquivo.bat
no Windows.Como as extensões de arquivo não são importantes no macOS e no Linux, você pode usar
.bat
como o até mesmo para scripts de shell.Não é possível executar arquivos
.bat
vazios. Se precisar de um script vazio, escreva um espaço nele.Use o Bash com base em princípios.
Nas regras de criação e teste do Starlark, use
ctx.actions.run_shell
para executar scripts Bash e Bash. comandos como ações.Nas macros do Starlark, una scripts e comandos Bash em uma classe
native.sh_binary()
ounative.genrule()
. O Bazel verifica se o Bash está disponível e executa o script ou comando pela Bash.Nas regras de repositório do Starlark, tente evitar o Bash completamente. No momento, não é possível executar o Bazel Comandos Bash com base em princípios nas regras de repositório.
Como excluir arquivos
Problemas:
Não é possível excluir arquivos enquanto eles estão abertos.
Arquivos abertos não podem ser excluídos (por padrão), as tentativas resultam em "Acesso negado" erros. Se não for possível excluir um arquivo, talvez ele ainda esteja armazenado por um processo em execução aberta.
Não é possível excluir o diretório de trabalho de um processo em execução.
Os processos têm um identificador aberto para o diretório de trabalho, e o diretório não pode ser excluído até que o processo seja encerrado.
Soluções:
No seu código, tente fechar os arquivos prontamente.
Em Java, use
try-with-resources
. Em Python, usewith open(...) as f:
. Em princípio, tente e feche as alças o mais rápido possível.