Nesta página, descrevemos como criar ou testar um projeto Xcode com o Bazel. Ela descreve as diferenças entre o Xcode e o Bazel e apresenta as etapas para converter um projeto Xcode em um projeto do Bazel. Ele também oferece solução de problemas e soluções para lidar com erros comuns.
Diferenças entre o Xcode e o Bazel
O Bazel exige que você especifique explicitamente cada destino de build e os respectivos dependências, além das configurações de build correspondentes via regras de build.
O Bazel exige que todos os arquivos necessários para o projeto estejam presentes no diretório do espaço de trabalho ou especificado como dependências no
MODULE.bazel
.Ao criar projetos do Xcode com o Bazel, os arquivos
BUILD
se tornam o fonte de verdade. Se você trabalha no projeto no Xcode, é necessário gerar um nova versão do projeto Xcode que corresponde aos arquivosBUILD
usando rules_xcodeproj sempre que você atualizar os arquivosBUILD
. Certas mudanças nos arquivosBUILD
como adicionar dependências a um destino, não exigem a regeneração do em um projeto, o que pode acelerar o desenvolvimento. Se você não estiver usando Xcode, a Os comandosbazel build
ebazel test
fornecem recursos de build e teste com algumas limitações descritas mais adiante neste guia.
Antes de começar
Antes de começar, faça o seguinte:
Instale o Bazel se ainda não tiver feito isso.
Se você não conhece o Bazel e os conceitos dele, conclua o app para iOS tutorial). Você já sabe como é o espaço de trabalho do Bazel, incluindo os arquivos
MODULE.bazel
eBUILD
, bem como os conceitos de regras de build e pacotes do Bazel.Analisar e entender as dependências do projeto.
Analisar as dependências do projeto
Ao contrário do Xcode, o Bazel exige que você declare explicitamente todas as dependências para
para cada destino no arquivo BUILD
.
Para mais informações sobre dependências externas, consulte Como trabalhar com recursos externos dependências.
Criar ou testar um projeto do Xcode com o Bazel
Para criar ou testar um projeto do Xcode com o Bazel, faça o seguinte:
Etapa 1: criar o arquivo MODULE.bazel
Crie um arquivo MODULE.bazel
em um novo diretório. Esse diretório se torna o
Raiz do espaço de trabalho do Bazel. Se o projeto não usa dependências externas, esse arquivo
pode estar vazio. Se o projeto depender de arquivos ou pacotes que não estão em um dos
diretórios do projeto, especifique essas dependências externas nos
MODULE.bazel
.
Etapa 2: (experimental) integrar dependências do SwiftPM
Para integrar dependências do SwiftPM ao espaço de trabalho do Bazel com swift_bazel, será preciso converta-os em pacotes do Bazel, conforme descrito nos tutorial ,
Etapa 3: criar um arquivo BUILD
Depois de definir o espaço de trabalho e as dependências externas, você precisa
criar um arquivo BUILD
que informe ao Bazel como o projeto está estruturado. Crie o
BUILD
na raiz do espaço de trabalho do Bazel e configure-o para fazer uma
build inicial do projeto da seguinte forma:
- Etapa 3a: adicionar o destino do aplicativo
- Etapa 3b: adicionar os destinos do teste (opcional)
- Etapa 3c: adicionar destinos da biblioteca
Dica:para saber mais sobre pacotes e outros conceitos do Bazel, consulte Espaços de trabalho, pacotes e destinos.
Etapa 3a: adicionar o aplicativo de destino
Adicione um
macos_application
ou um
ios_application
destino da regra de destino. Esse destino cria um pacote de aplicativos macOS ou iOS, respectivamente.
No destino, especifique pelo menos o seguinte:
bundle_id
: ID do pacote (caminho do DNS reverso seguido pelo nome do app) das binário.provisioning_profile
: perfil de provisionamento do seu desenvolvedor da Apple (ao criar para um dispositivo iOS).families
(somente iOS): se o aplicativo será criado para iPhone, iPad, ou ambos.infoplists
: lista de arquivos .plist a serem mesclados no arquivo Info.plist final.minimum_os_version
: a versão mínima do macOS ou iOS que o que o aplicativo suporta. Isso garante que o Bazel crie o aplicativo com a com os níveis corretos de API.
Etapa 3b: adicionar os destinos do teste (opcional)
Build da Apple do Bazel de código oferecem suporte à execução testes de unidade e de interface em todas as plataformas da Apple. Adicione destinos de teste da seguinte maneira:
macos_unit_test
para executar testes de unidade baseados em aplicativos e em bibliotecas em um macOS.ios_unit_test
para criar e executar testes de unidade baseados em biblioteca no iOS.ios_ui_test
para criar e executar testes de interface do usuário no simulador para iOS.Existem regras de teste semelhantes para tvOS watchOS e visionOS (em inglês).
Especifique no mínimo um valor para o atributo minimum_os_version
.
outros atributos de empacotamento, como bundle_identifier
e infoplists
;
usar os valores mais usados como padrão, verifique se esses padrões são compatíveis
com o projeto e ajustá-las conforme necessário. Para testes que exigem o iOS
simulador, especifique também o nome de destino ios_application
como o valor do
test_host
.
Etapa 3c: adicionar destinos da biblioteca
Adicione um destino objc_library
para cada
biblioteca Objective-C e uma
swift_library
para cada biblioteca Swift da qual o aplicativo e/ou os testes dependem.
Adicione os destinos da biblioteca da seguinte maneira:
Adicionar os destinos da biblioteca do aplicativo como dependências de destino.
Adicione os destinos da biblioteca de teste como dependências aos destinos de teste.
Liste as origens de implementação no atributo
srcs
.Liste os cabeçalhos no atributo
hdrs
.
Você pode procurar exemplos existentes para vários tipos de aplicativos diretamente no os exemplos de rules_apple diretório atual. Por exemplo:
Para obter mais informações sobre regras de criação, consulte Regras da Apple para Bazel.
Neste ponto, é uma boa ideia testar o build:
bazel build //:<application_target>
Etapa 4 (opcional): detalhar o build
Se o projeto for grande ou conforme ele crescer, considere dividi-lo em vários pacotes do Bazel. Esse aumento de granularidade oferece:
Maior incrementabilidade de builds,
Maior carregamento em paralelo de tarefas de compilação,
Melhor capacidade de manutenção para futuros usuários
Melhor controle sobre a visibilidade do código-fonte entre destinos e pacotes. Isso evita o vazamento de problemas como bibliotecas que contêm detalhes de implementação em APIs públicas.
Dicas para granular o projeto:
colocar cada biblioteca no próprio pacote do Bazel. Comece com aqueles que exigem menos dependências e subir na árvore de dependências.
À medida que você adicionar arquivos
BUILD
e especificar destinos, adicione esses novos destinos aodeps
atributos de destinos que dependem deles.A função
glob()
não ultrapassa os limites dos pacotes, então, como o número de os pacotes aumentam, os arquivos correspondidos porglob()
serão reduzidos.Ao adicionar um arquivo
BUILD
a um diretóriomain
, adicione também um arquivoBUILD
ao no diretóriotest
correspondente.Aplique limites de visibilidade íntegros nos pacotes.
Criar o projeto após cada grande mudança nos arquivos
BUILD
e corrigir o build os erros à medida que os encontra.
Etapa 5: executar o build
Execute o build totalmente migrado para garantir que ele seja concluído sem erros ou avisos. Execute todos os aplicativos e destinos de teste individualmente para encontrar origens com mais facilidade todos os erros ocorridos.
Exemplo:
bazel build //:my-target
Etapa 6: gerar o projeto Xcode com rules_xcodeproj
Ao criar com o Bazel, os arquivos MODULE.bazel
e BUILD
se tornam a origem.
de verdade sobre o build. Para informar isso ao Xcode, gere uma
projeto Xcode compatível com Bazel usando
rules_xcodeproj
,
Solução de problemas
Erros do Bazel podem surgir quando ele fica dessincronizado com a versão selecionada do Xcode. como quando você aplica uma atualização. Confira o que você pode fazer se estiver Há erros no Xcode, por exemplo, "A versão do Xcode deve ser especificada para use uma CROSSTOOL da Apple".
Execute o Xcode manualmente e aceite os Termos e Condições.
Use Xcode select para indicar a versão correta, aceitar a licença e limpar o estado do Bazel.
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -license
bazel sync --configure
- Se isso não funcionar, tente executar
bazel clean --expunge
.