Esta página descreve como criar ou testar um projeto do Xcode com o Bazel. Ela descreve as diferenças entre o Xcode e o Bazel e fornece as etapas para converter um projeto do Xcode em um projeto do Bazel. Ela também oferece soluções de problemas para resolver erros comuns.
Diferenças entre o Xcode e o Bazel
O Bazel exige que você especifique explicitamente cada destino de build e as dependências dele, além das configurações de build correspondentes usando regras de build.
O Bazel exige que todos os arquivos dos quais o projeto depende estejam presentes no diretório do espaço de trabalho ou especificados como dependências no arquivo
MODULE.bazel.Ao criar projetos do Xcode com o Bazel, os arquivos
BUILDse tornam a fonte da verdade. Se você trabalhar no projeto no Xcode, será necessário gerar uma nova versão do projeto do Xcode que corresponda aos arquivosBUILDusando rules_xcodeproj sempre que atualizar os arquivosBUILD. Algumas mudanças nos arquivosBUILD, como a adição de dependências a um destino, não exigem a regeneração do projeto, o que pode acelerar o desenvolvimento. Se você não estiver usando o Xcode, os comandosbazel buildebazel testvão fornecer 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 estiver familiarizado com o Bazel e os conceitos dele, conclua o tutorial do app iOS). Você precisa entender o espaço de trabalho do Bazel, incluindo os arquivos
MODULE.bazeleBUILD, bem como os conceitos de destinos, regras de build e pacotes do Bazel.Analise e entenda as dependências do projeto.
Analisar dependências do projeto
Ao contrário do Xcode, o Bazel exige que você declare explicitamente todas as dependências de cada destino no arquivo BUILD.
Para mais informações sobre dependências externas, consulte Trabalhar com dependências externas.
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 a raiz do espaço de trabalho do Bazel. Se o projeto não usar dependências externas, esse arquivo poderá ficar 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 no arquivo 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, é necessário convertê-las em pacotes do Bazel, conforme descrito neste tutorial .
Etapa 3: criar um arquivo BUILD
Depois de definir o espaço de trabalho e as dependências externas, é necessário criar um arquivo BUILD que informe ao Bazel como o projeto está estruturado. Crie o arquivo BUILD na raiz do espaço de trabalho do Bazel e configure-o para fazer um build inicial do projeto da seguinte maneira:
- Etapa 3a: adicionar o destino do aplicativo
- Etapa 3b: (opcional) adicionar os destinos de teste
- Etapa 3c: adicionar os 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 destino do aplicativo
Adicione um
macos_application
ou um
ios_application
destino de regra. Esse destino cria um pacote de aplicativo macOS ou iOS, respectivamente.
No destino, especifique o seguinte no mínimo:
bundle_id- o ID do pacote (caminho de DNS reverso seguido pelo nome do app) do binário.provisioning_profile- perfil de provisionamento da sua conta de desenvolvedor da Apple (se você estiver criando 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 compatível com o aplicativo. Isso garante que o Bazel crie o aplicativo com os níveis de API corretos.
Etapa 3b: (opcional) adicionar os destinos de teste
As regras de build da Apple do Bazel oferecem suporte à execução de testes de unidade e de interface em todas as plataformas da Apple. Adicione destinos de teste da seguinte maneira:
macos_unit_testpara executar testes de unidade baseados em biblioteca e aplicativo em um macOS.ios_unit_testpara criar e executar testes de unidade baseados em biblioteca no iOS.ios_ui_testpara criar e executar testes de interface do usuário no simulador do iOS.Regras de teste semelhantes existem para tvOS, watchOS e visionOS.
No mínimo, especifique um valor para o atributo minimum_os_version. Embora outros atributos de empacotamento, como bundle_identifier e infoplists, sejam definidos como os valores usados com frequência, verifique se esses padrões são compatíveis com o projeto e ajuste-os conforme necessário. Para testes que exigem o simulador do iOS, também especifique o nome do destino ios_application como o valor do atributo test_host.
Etapa 3c: adicionar os destinos da biblioteca
Adicione um objc_library destino para cada
biblioteca Objective-C e um
swift_library
destino para cada biblioteca Swift da qual o aplicativo e/ou os testes dependem.
Adicione os destinos da biblioteca da seguinte maneira:
Adicione os destinos da biblioteca de aplicativos como dependências aos destinos do aplicativo.
Adicione os destinos da biblioteca de testes como dependências aos destinos de teste.
Liste as fontes de implementação no atributo
srcs.Liste os cabeçalhos no atributo
hdrs.
É possível navegar pelos exemplos atuais de vários tipos de aplicativos diretamente em o diretório de exemplos rules_apple. Por exemplo:
Para mais informações sobre regras de build, consulte Regras da Apple para Bazel.
Nesse momento, é recomendável testar o build:
bazel build //:<application_target>
Etapa 4: (opcional) granularizar o build
Se o projeto for grande ou à medida que ele crescer, considere dividi-lo em vários pacotes do Bazel. Essa granularidade aumentada oferece:
Maior incrementalidade de builds
Maior paralelização de tarefas de build
Melhor capacidade de manutenção para usuários futuros
Melhor controle sobre a visibilidade do código-fonte em destinos e pacotes. Isso evita problemas como bibliotecas que contêm detalhes de implementação que vazam para APIs públicas.
Dicas para granularizar o projeto:
Coloque cada biblioteca no próprio pacote do Bazel. Comece com aqueles que exigem o menor número de dependências e trabalhe na árvore de dependências.
À medida que você adiciona arquivos
BUILDe especifica destinos, adicione esses novos destinos aos atributosdepsdos destinos que dependem deles.A função
glob()não cruza os limites do pacote. Portanto, à medida que o número de pacotes aumenta, os arquivos correspondentes aglob()diminuem.Ao adicionar um arquivo
BUILDa um diretóriomain, adicione também um arquivoBUILDao diretóriotestcorrespondente.Aplique limites de visibilidade saudáveis em todos os pacotes.
Crie o projeto após cada mudança importante nos arquivos
BUILDe corrija os erros de build à medida que eles forem encontrados.
Etapa 5: executar o build
Execute o build totalmente migrado para garantir que ele seja concluído sem erros ou avisos. Execute cada aplicativo e destino de teste individualmente para encontrar mais facilmente as fontes de erros que ocorrem.
Por exemplo:
bazel build //:my-targetEtapa 6: gerar o projeto do Xcode com rules_xcodeproj
Ao criar com o Bazel, os arquivos MODULE.bazel e BUILD se tornam a fonte da verdade sobre o build. Para que o Xcode reconheça isso, é necessário gerar um
projeto do Xcode compatível com o Bazel usando
rules_xcodeproj
.
Solução de problemas
Os erros do Bazel podem ocorrer quando ele fica dessincronizado com a versão selecionada do Xcode, como quando você aplica uma atualização. Confira algumas coisas a serem tentadas se você estiver tendo erros com o Xcode, por exemplo, "A versão do Xcode precisa ser especificada para usar um CROSSTOOL da Apple".
Execute o Xcode manualmente e aceite os Termos e Condições.
Use o Xcode select para indicar a versão correta, aceite a licença e limpe o estado do Bazel.
sudo xcode-select -s /Applications/Xcode.app/Contents/Developersudo xcodebuild -licensebazel sync --configure
- Se isso não funcionar, tente executar
bazel clean --expunge.