O Bazel tem suporte sofisticado para modelagem plataformas e conjuntos de ferramentas para multiarquitetura e builds de compilação cruzada.
Esta página resume o estado desse suporte.
Consulte também:
Status
C++
As regras de C++ usam plataformas para selecionar conjuntos de ferramentas quando
--incompatible_enable_cc_toolchain_resolution
está definido.
Isso significa que é possível configurar um projeto C++ com:
bazel build //:my_cpp_project --platforms=//:myplatform
em vez da legada:
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 Como migrar seu projeto e Como configurar conjuntos de ferramentas para C++.
Java
As regras Java usam plataformas para selecionar conjuntos de ferramentas.
Isso substitui as sinalizações 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 é possível configurar um projeto Android com:
bazel build //:my_android_project --android_platforms=//:my_android_platform
em vez de sinalizações 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 Android com plataformas, consulte Como migrar seu projeto.
Apple
As regras da Apple não são compatíveis com plataformas e ainda não foram programadas para receber ajuda.
Você ainda pode usar APIs de plataforma com builds da Apple (por exemplo, ao criar com uma mistura de regras da Apple e C++ puro) com o platform mapeamentos.
Outros idiomas
- As regras do Go oferecem suporte total a plataformas
- As regras do Rust têm suporte total a plataformas.
Se você for o proprietário de um conjunto de regras de idioma, consulte Como migrar seu conjunto de regras para adicionar suporte.
Contexto
Plataformas e conjuntos de ferramentas foram introduzidos para padronizar a forma como os softwares os projetos têm arquiteturas diferentes e fazem compilação cruzada.
Isso foi
inspirado
ao observar que os mantenedores da linguagem já estavam fazendo isso em campanhas
de formas incompatíveis e hoc. Por exemplo, as regras C++ usaram --cpu
e
--crosstool_top
para declarar uma CPU de destino e um conjunto de ferramentas. Nenhuma das alternativas
modela corretamente uma "plataforma". Isso produzia builds estranhos e incorretos.
Java, Android e outras linguagens evoluíram suas próprias flags para fins semelhantes, e nenhuma interoperava entre si. Isso fez com que os builds em várias linguagens confusas e complicadas.
O Bazel é destinado a projetos grandes, com várias linguagens e várias plataformas. Isso exige um apoio mais fundamentado para esses conceitos, incluindo uma explicação a API padrão.
Necessidade de migração
O upgrade para a nova API requer dois esforços: lançamento da API e upgrade lógica de regras para usá-lo.
A primeira foi concluída, mas a segunda ainda está em andamento. Isso consiste em garantir
são definidas as plataformas e os conjuntos de ferramentas específicos da linguagem, as leituras da lógica da linguagem
de ferramentas por meio da nova API em vez de sinalizações antigas, como --crosstool_top
.
config_setting
s são selecionados na nova API em vez das sinalizações antigas.
Esse trabalho é simples, mas requer um esforço distinto para cada linguagem, e um aviso justo para que os proprietários do projeto testem as próximas mudanças.
Por isso, essa migração está em andamento.
Meta
Essa migração é concluída quando todos os projetos são criados com o formulário:
bazel build //:myproject --platforms=//:myplatform
Isso implica:
- As regras do projeto escolhem os conjuntos de ferramentas certos para
//:myplatform
. - As dependências do projeto escolhem os conjuntos de ferramentas certos para
//:myplatform
. //:myplatform
referências declarações comuns deCPU
,OS
e outras propriedades genéricas e independentes de linguagem- Todos os
select()
s relevantes correspondem corretamente a//:myplatform
. //:myplatform
seja definido em um local claro e acessível: no arquivo se a plataforma for exclusiva do seu projeto ou algum lugar em comum projetos de consumo podem encontrá-los
As flags antigas, como --cpu
, --crosstool_top
e --fat_apk_cpu
, serão
descontinuada e removida assim que for possível.
Essa será a única maneira de configurar arquiteturas.
Como migrar seu projeto
Se você usa linguagens que aceitam plataformas, seu build já deve trabalhe com uma invocação como:
bazel build //:myproject --platforms=//:myplatform
Consulte o Status e a documentação da sua linguagem para conferir detalhes precisos.
Se um idioma exigir uma flag para ativar o suporte à plataforma, também será necessário definir a sinalização. Consulte o Status para saber mais.
Para que seu projeto seja criado, verifique o seguinte:
//:myplatform
precisa existir. Geralmente, é responsabilidade do proprietário do projeto para definir plataformas porque projetos diferentes visam máquinas distintas. Consulte Plataformas padrão.Os conjuntos de ferramentas que você quer usar precisam existir. Se você usa conjuntos de ferramentas de estoque, a os proprietários de linguagens de programação devem incluir instruções sobre como registrá-los. Se gravando seus próprios conjuntos de ferramentas personalizados, é necessário registrá-los no
WORKSPACE
ou com--extra_toolchains
.select()
s e transições de configuração precisam resolver adequadamente. Consulte select() e Transitions.Caso seu build combine linguagens que tenham e que não sejam compatíveis com plataformas, é possível precisam de mapeamentos de plataforma para que as linguagens legadas funcionem com a nova API. Consulte Mapeamentos de plataforma para mais detalhes.
Se você ainda tiver problemas, entre em contato para receber suporte.
Plataformas padrão
Os proprietários do projeto precisam definir
platforms para descrever as arquiteturas
eles querem criar. Em seguida, elas são acionadas com --platforms
.
Quando --platforms
não está definido, o padrão do Bazel é usar um platform
representando o
máquina de build local. Gerado automaticamente em @platforms//host
(com alias:
@bazel_tools//tools:host_platform
).
portanto, não é necessário defini-lo explicitamente. Ela mapeia o OS
da máquina local
e CPU
com constraint_value
s declarados em
@platforms
select()
Os projetos podem select()
em
constraint_value
destinos, mas não concluídos
plataformas. Isso é intencional para que select()
ofereça suporte a uma grande variedade de
o máximo possível de máquinas. Uma biblioteca com fontes específicas de ARM
vai oferecer suporte a todos
Máquinas com tecnologia ARM
, a menos que haja um motivo para ser mais específico.
Para selecionar em um ou mais constraint_value
s, use:
config_setting(
name = "is_arm",
constraint_values = [
"@platforms//cpu:arm",
],
)
Isso equivale a selecionar tradicionalmente --cpu
:
config_setting(
name = "is_arm",
values = {
"cpu": "arm",
},
)
Confira mais detalhes neste link.
select
s no --cpu
, --crosstool_top
etc. não entendem --platforms
.
Ao migrar seu projeto para as plataformas, você precisa convertê-las em
constraint_values
ou use mapeamentos de plataforma para dar suporte
os dois estilos durante a migração.
Transições
As transições Starlark mudam
sinaliza partes do seu gráfico de build. Se o seu projeto usa uma transição que
define --cpu
, --crossstool_top
ou outras sinalizações legadas, regras que leem
--platforms
não terá acesso a essas mudanças.
Ao migrar seu projeto para as plataformas, você precisa converter mudanças como
return { "//command_line_option:cpu": "arm" }
para return {
"//command_line_option:platforms": "//:my_arm_platform" }
ou use platform
mapeamentos para oferecer suporte aos dois estilos durante a migração.
janela.
Migrando seu conjunto de regras
Se você tem um grupo de regras e quer oferecer suporte a plataformas, precisa:
Fazer com que a lógica de regras resolva os conjuntos de ferramentas com a API correspondente. Consulte API Dataset (
ctx.toolchains
).Opcional: defina uma flag
--incompatible_enable_platforms_for_my_language
para a lógica de regras resolve alternadamente os conjuntos de ferramentas usando a nova API ou as flags antigas. como--crosstool_top
durante o teste de migração.Defina as propriedades relevantes que compõem os componentes da plataforma. Consulte Propriedades comuns da plataforma
Definir os conjuntos de ferramentas padrão e torná-los acessíveis aos usuários por meio da instruções de registro da regra (detalhes)
Garantir que
select()
s e transições de configuração oferecem suporte a plataformas. Esta é a o maior desafio. É um desafio particularmente desafiador para projetos com várias linguagens. (o que pode falhar se todos os idiomas não puderem ler--platforms
).
Se você precisar misturar regras sem suporte a plataformas, talvez seja necessário mapeamentos de plataforma para preencher a lacuna.
Propriedades comuns da plataforma
Propriedades comuns de plataformas em vários idiomas, como OS
e CPU
, precisam ser
declarado 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 delas. Isso permite que você mantenha uma propriedade clara sobre os conceitos específicos às quais suas regras estão é responsável.
Se as regras usarem CPUs ou SOs personalizados, eles deverão ser declarados no
do Compute Engine x
@platforms
Mapeamentos de plataforma
Os mapeamentos de plataforma são uma API temporária que permite combinar lógicas com reconhecimento de plataforma lógica legada no mesmo build. Essa é uma ferramenta sem fio destinada apenas a incompatibilidades suaves com diferentes períodos de migração.
Um mapeamento de plataforma é um mapa de um platform()
para um
o conjunto correspondente de sinalizações legadas ou vice-versa. Exemplo:
platforms:
# Maps "--platforms=//platforms:ios" to "--cpu=ios_x86_64 --apple_platform_type=ios".
//platforms:ios
--cpu=ios_x86_64
--apple_platform_type=ios
flags:
# Maps "--cpu=ios_x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
--cpu=ios_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 todas as configurações, tanto as baseadas na plataforma quanto legados, são aplicadas de modo consistente em todo o build, inclusive por meio da transições.
Por padrão, o Bazel lê os mapeamentos do arquivo platform_mappings
na sua
raiz do espaço de trabalho. Você também pode definir
--platform_mappings=//:my_custom_mapping
:
Consulte o design de mapeamentos de plataforma para mais detalhes.
Revisão da API
Uma platform
é uma coleção de
constraint_value
destinos:
platform(
name = "myplatform",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:arm",
],
)
Um constraint_value
é uma máquina
. Valores do mesmo "tipo" são agrupadas em um mesmo
constraint_setting
:
constraint_setting(name = "os")
constraint_value(
name = "linux",
constraint_setting = ":os",
)
constraint_value(
name = "mac",
constraint_setting = ":os",
)
Uma toolchain
é uma regra Starlark. Seu
Os atributos declaram as ferramentas de uma linguagem (como compiler =
"//mytoolchain:custom_gcc"
). Os provedores transmitem
essas informações às regras que precisam ser criadas com essas ferramentas.
Os conjuntos de ferramentas declaram os constraint_value
s de máquinas que podem
target
(target_compatible_with = ["@platforms//os:linux"]
) e as máquinas que as ferramentas
executar em
(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 do conjunto de ferramentas.
O conjunto de conjuntos de ferramentas disponíveis pode ser registrado no WORKSPACE
com
register_toolchains
ou no
linha de comando com --extra_toolchains
.
Clique aqui para mais informações.
Perguntas
Para suporte geral e dúvidas 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 da plataforma/conjunto de ferramentas, entre em contato com bazel-dev.