O Bazel oferece suporte sofisticado para modelagem de plataformas e conjuntos de ferramentas para builds de várias arquiteturas e compilados cruzados.
Esta página resume o estado desse suporte.
Consulte também:
Status
C++
As regras do C++ usam plataformas para selecionar conjuntos de ferramentas quando
--incompatible_enable_cc_toolchain_resolution está definido.
Isso significa que você pode configurar um projeto em C++ com:
bazel build //:my_cpp_project --platforms=//:myplatformem vez do legado:
bazel build //:my_cpp_project` --cpu=... --crosstool_top=... --compiler=...Isso será ativado por padrão no Bazel 7.0 (#7260).
Para testar seu projeto em C++ com plataformas, consulte Migrar seu projeto e Configurar conjuntos de ferramentas em C++.
Java
As regras do Java usam plataformas para selecionar conjuntos de ferramentas.
Isso substitui as flags legadas --java_toolchain, --host_java_toolchain,
--javabase e --host_javabase.
Consulte Java e Bazel para mais detalhes.
Android
As regras do Android usam plataformas para selecionar conjuntos de ferramentas quando
--incompatible_enable_android_toolchain_resolution está definido.
Isso significa que você pode configurar um projeto do Android com:
bazel build //:my_android_project --android_platforms=//:my_android_platformem vez de flags legadas como --android_crosstool_top, --android_cpu,
e --fat_apk_cpu.
Isso será ativado por padrão no Bazel 7.0 (#16285).
Para testar seu projeto do Android com plataformas, consulte Migrar seu projeto.
Apple
As regras da Apple não oferecem suporte a plataformas e ainda não estão programadas para isso.
Ainda é possível usar APIs de plataforma com builds da Apple (por exemplo, ao criar com uma mistura de regras da Apple e C++ puro) com mapeamentos de plataforma.
Outros idiomas
- As regras do Go oferecem suporte total a plataformas.
- As regras do Rust oferecem suporte total a plataformas.
Se você tiver um conjunto de regras de linguagem, consulte Migrar seu conjunto de regras para adicionar suporte.
Contexto
As plataformas e os conjuntos de ferramentas foram introduzidos para padronizar como os projetos de software segmentam diferentes arquiteturas e compilam cruzados.
Isso foi
inspirado
na observação de que os mantenedores de linguagem já estavam fazendo isso de maneiras ad
hoc e incompatíveis. Por exemplo, as regras do C++ usavam --cpu e
--crosstool_top para declarar uma CPU e um conjunto de ferramentas de destino. Nenhum deles
modela corretamente uma "plataforma". Isso produziu builds estranhos e incorretos.
Java, Android e outras linguagens desenvolveram suas próprias flags para fins semelhantes, mas nenhuma delas interoperava entre si. Isso tornou os builds entre linguagens confusos e complicados.
O Bazel é destinado a projetos grandes, multilíngues e multiplataformas. Isso exige um suporte mais fundamentado para esses conceitos, incluindo uma API padrão clara.
Necessidade de migração
A atualização para a nova API exige dois esforços: lançar a API e atualizar a lógica de regras para usá-la.
O primeiro já foi feito, mas o segundo está em andamento. Isso consiste em garantir que plataformas e conjuntos de ferramentas específicos da linguagem sejam definidos, que a lógica de linguagem leia conjuntos de ferramentas pela nova API em vez de flags antigas como --crosstool_top e que config_settings sejam selecionados na nova API em vez de flags antigas.
Esse trabalho é simples, mas exige um esforço distinto para cada linguagem, além de um aviso justo para que os proprietários do projeto testem as mudanças futuras.
É por isso que essa é uma migração contínua.
Meta
Essa migração será concluída quando todos os projetos forem criados com o formulário:
bazel build //:myproject --platforms=//:myplatformIsso implica:
- As regras do seu projeto escolhem os conjuntos de ferramentas certos para
//:myplatform. - As dependências do seu projeto escolhem os conjuntos de ferramentas certos para
//:myplatform. //:myplatformfaz referência a declarações comuns deCPU,OSe outras propriedades genéricas e independentes de linguagem.- Todos os
select()s relevantes correspondem corretamente a//:myplatform. //:myplatformé definido em um lugar claro e acessível: no repositório do seu projeto, se a plataforma for exclusiva dele, ou em um lugar comum que todos os projetos consumidores possam encontrar.
Flags antigas como --cpu, --crosstool_top e --fat_apk_cpu serão
descontinuadas e removidas assim que for seguro fazer isso.
Por fim, essa será a única maneira de configurar arquiteturas.
Migrar seu projeto
Se você criar com linguagens que oferecem suporte a plataformas, o build já vai funcionar com uma invocação como:
bazel build //:myproject --platforms=//:myplatformConsulte Status e a documentação da sua linguagem para detalhes precisos.
Se uma linguagem exigir uma flag para ativar o suporte à plataforma, você também precisará definir essa flag. Consulte Status para mais detalhes.
Para que seu projeto seja criado, você precisa verificar o seguinte:
//:myplatformprecisa existir. Geralmente, é responsabilidade do proprietário do projeto definir plataformas, porque projetos diferentes segmentam máquinas diferentes. Consulte Plataformas padrão.Os conjuntos de ferramentas que você quer usar precisam existir. Se você estiver usando conjuntos de ferramentas padrão, os proprietários da linguagem precisarão incluir instruções sobre como registrá-los. Se você estiver criando seus próprios conjuntos de ferramentas personalizados, precisará registrá-los no seu
MODULE.bazelarquivo ou com--extra_toolchains.select()s e as transições de configuração precisam ser resolvidas corretamente. Consulte select() e Transições.Se o build misturar linguagens que oferecem e não oferecem suporte a plataformas, talvez você precise de mapeamentos de plataforma para ajudar as linguagens legadas a trabalhar com a nova API. Consulte Mapeamentos de plataforma para mais detalhes.
Se você ainda tiver problemas, entre em contato com o suporte.
Plataformas padrão
Os proprietários do projeto precisam definir plataformas explícitas
para descrever as arquiteturas
para as quais querem criar. Elas são acionadas com --platforms.
Quando --platforms não está definido, o Bazel usa como padrão uma platform que representa a
máquina de build local. Isso é gerado automaticamente em @platforms//host (com alias
@bazel_tools//tools:host_platform)
então não é necessário defini-lo explicitamente. Ele mapeia o OS
e CPU da máquina local com constraint_values declarados em
@platforms.
select()
Os projetos podem select() em
constraint_value destinos mas não em plataformas completas. Isso é intencional para que select() ofereça suporte ao maior número possível de
máquinas. Uma biblioteca com fontes específicas de ARM precisa oferecer suporte a todas
as máquinas com tecnologia ARM, a menos que haja um motivo para ser mais específico.
Para selecionar um ou mais constraint_values, use:
config_setting(
name = "is_arm",
constraint_values = [
"@platforms//cpu:arm",
],
)
Isso é equivalente à seleção tradicional em --cpu:
config_setting(
name = "is_arm",
values = {
"cpu": "arm",
},
)
Veja mais detalhes aqui.
selects em --cpu, --crosstool_top etc. não entendem --platforms.
Ao migrar seu projeto para plataformas, você precisa convertê-los em
constraint_values ou usar mapeamentos de plataforma para oferecer suporte
aos dois estilos durante a migração.
Transições
As transições do Starlark mudam
as flags em partes do gráfico de build. Se o projeto usar uma transição que
define --cpu, --crossstool_top, ou outras flags legadas, as regras que leem
--platforms não vão ver essas mudanças.
Ao migrar seu projeto para plataformas, você precisa converter mudanças como
return { "//command_line_option:cpu": "arm" } em return {
"//command_line_option:platforms": "//:my_arm_platform" } ou usar mapeamentos de plataforma para oferecer suporte aos dois estilos durante a migração.
janela.
Migrar seu conjunto de regras
Se você tiver um conjunto de regras e quiser oferecer suporte a plataformas, faça o seguinte:
Faça com que a lógica de regras resolva conjuntos de ferramentas com a API de conjunto de ferramentas. Consulte a API de conjunto de ferramentas (
ctx.toolchains).Opcional: defina uma flag
--incompatible_enable_platforms_for_my_languagepara que a lógica de regras resolva conjuntos de ferramentas alternadamente pela nova API ou flags antigas como--crosstool_topdurante os testes de migração.Defina as propriedades relevantes que compõem os componentes da plataforma. Consulte Propriedades comuns da plataforma
Defina conjuntos de ferramentas padrão e disponibilize-os aos usuários pelas instruções de registro da regra (detalhes)
Garanta que os
select()s e as transições de configuração ofereçam suporte a plataformas. Esse é o maior desafio. É particularmente desafiador para projetos multilíngues (que podem falhar se todas as linguagens não puderem ler--platforms).
Se você precisar misturar com regras que não oferecem suporte a plataformas, talvez precise de mapeamentos de plataforma para preencher a lacuna.
Propriedades comuns da plataforma
Propriedades comuns de plataforma entre linguagens, como OS e CPU, precisam ser
declaradas em @platforms.
Isso incentiva o compartilhamento, a padronização e a compatibilidade entre linguagens.
As propriedades exclusivas das suas regras precisam ser declaradas no repositório da regra. Isso permite que você mantenha a propriedade clara dos conceitos específicos de que suas regras são responsáveis.
Se as regras usarem SOs ou CPUs de finalidade personalizada, elas precisarão ser declaradas no
repositório da regra em vez de
@platforms.
Mapeamentos de plataforma
Os mapeamentos de plataforma são uma API temporária que permite que a lógica com reconhecimento de plataforma seja misturada com a lógica legada no mesmo build. Essa é uma ferramenta simples destinada apenas a suavizar incompatibilidades com diferentes prazos de migração.
Um mapeamento de plataforma é um mapa de uma platform() para um
conjunto correspondente de flags legadas ou o inverso. Por exemplo:
platforms:
# Maps "--platforms=//platforms:ios" to "--ios_multi_cpus=x86_64 --apple_platform_type=ios".
//platforms:ios
--ios_multi_cpus=x86_64
--apple_platform_type=ios
flags:
# Maps "--ios_multi_cpus=x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
--ios_multi_cpus=x86_64
--apple_platform_type=ios
//platforms:ios
# Maps "--cpu=darwin_x86_64 --apple_platform_type=macos" to "//platform:macos".
--cpu=darwin_x86_64
--apple_platform_type=macos
//platforms:macos
O Bazel usa isso para garantir que todas as configurações, baseadas em plataforma e legadas, sejam aplicadas de maneira consistente em todo o build, incluindo transições.
Por padrão, o Bazel lê mapeamentos do arquivo platform_mappings na raiz do seu
espaço de trabalho. Também é possível definir
--platform_mappings=//:my_custom_mapping.
Consulte o design de mapeamentos de plataforma para mais detalhes.
Revisão pela API
Um platform é uma coleção de destinos
constraint_value:
platform(
name = "myplatform",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:arm",
],
)
Um constraint_value é uma propriedade
da máquina. Valores do mesmo "tipo" são agrupados em um
constraint_setting comum:
constraint_setting(name = "os")
constraint_value(
name = "linux",
constraint_setting = ":os",
)
constraint_value(
name = "mac",
constraint_setting = ":os",
)
Um toolchain é uma regra do Starlark. Os
atributos dele declaram as ferramentas de uma linguagem (como compiler =
"//mytoolchain:custom_gcc"). Os provedores transmitem
essas informações para regras que precisam ser criadas com essas ferramentas.
Os conjuntos de ferramentas declaram os constraint_values das máquinas que podem
segmentar
(target_compatible_with = ["@platforms//os:linux"]) e as máquinas em que as ferramentas podem
ser executadas
(exec_compatible_with = ["@platforms//os:mac"]).
Ao criar $ bazel build //:myproject --platforms=//:myplatform, o Bazel
seleciona automaticamente um conjunto de ferramentas que pode ser executado na máquina de build e
criar binários para //:myplatform. Isso é conhecido como resolução de conjunto de ferramentas.
O conjunto de conjuntos de ferramentas disponíveis pode ser registrado no arquivo MODULE.bazel com register_toolchains ou na linha de comando com --extra_toolchains.
Para mais informações, consulte este link.
Perguntas
Para suporte geral e perguntas sobre o cronograma de migração, entre em contato com bazel-discuss ou os proprietários das regras apropriadas.
Para discussões sobre o design e a evolução das APIs de plataforma/conjunto de ferramentas, entre em contato com bazel-dev.