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 descreve as etapas para converter um projeto do Xcode em um projeto do Bazel. Ele também fornece soluções de problemas 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 as dependências, além das configurações de build correspondentes usando regras de build.
O Bazel exige que todos os arquivos de que o projeto depende estejam presentes no diretório do espaço de trabalho ou sejam especificados como importações no arquivo
WORKSPACE
.Ao criar projetos do Xcode com o Bazel, os arquivos
BUILD
se tornam a fonte da verdade. Se você trabalhar no projeto no Xcode, gere uma nova versão do projeto que corresponda aos arquivosBUILD
usando rules_xcodeproj sempre que atualizar os arquivosBUILD
. Certas mudanças nos arquivosBUILD
, como a adição de dependências a um destino, não exigem regenerar o projeto, o que pode acelerar o desenvolvimento. Se você não usa o Xcode, os comandosbazel build
ebazel test
oferecem 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 você ainda não fez isso.
Se você não conhece 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
WORKSPACE
eBUILD
, bem como os conceitos de destinos, 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
cada destino no arquivo BUILD
.
Para mais informações sobre dependências externas, consulte Como trabalhar com dependências externas.
Criar ou testar um projeto do Xcode com o Bazel
Para criar ou testar um projeto Xcode com o Bazel, faça o seguinte:
Etapa 1: criar o arquivo WORKSPACE
Crie um arquivo WORKSPACE
em um novo diretório. Esse diretório se torna a raiz do espaço de trabalho
do Bazel. Se o projeto não usa dependências externas, esse arquivo pode ficar
vazio. Se o projeto depender de arquivos ou pacotes que não estejam em um dos
diretórios do projeto, especifique essas dependências externas no arquivo
WORKSPACE
.
Etapa 2: (experimental) integrar dependências do SwiftPM
Para integrar dependências do SwiftPM no espaço de trabalho do Bazel com swift_bazel, converta-as em pacotes do Bazel, conforme descrito no tutorial a seguir.
Etapa 3: criar um arquivo BUILD
Depois de definir o espaço de trabalho e as dependências externas, crie 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 uma meta de regra macos_application
ou ios_application
. Esse destino cria um pacote de aplicativos macOS ou iOS, respectivamente.
Especifique pelo menos o seguinte no destino:
bundle_id
: o ID do pacote (caminho de DNS reverso seguido pelo nome do app) do binário.provisioning_profile
: perfil de provisionamento da conta de desenvolvedor da Apple (se estiver criando para um dispositivo iOS).families
(somente para iOS): indica 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: adicionar os destinos de teste (opcional)
As regras de build da Apple do Bazel são compatíveis com a execução de testes de unidade e IU em todas as plataformas da Apple. Adicione destinos de teste da seguinte maneira:
macos_unit_test
(link em inglês) para executar testes de unidade baseados em biblioteca e em aplicativos 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 de iOS.Há regras de teste semelhantes para tvOS, watchOS e visionOS.
Especifique pelo menos um valor para o atributo minimum_os_version
. Enquanto
outros atributos de empacotamento, como bundle_identifier
e infoplists
,
têm como padrão os valores mais usados, verifique se esses padrões são compatíveis
com o projeto e ajuste-os conforme necessário. Para testes que exigem o simulador de iOS, especifique também o nome do destino ios_application
como o valor do
atributo test_host
.
Etapa 3c: adicionar os destinos da biblioteca
Adicione um destino objc_library
para cada biblioteca Objective-C e um destino swift_library
para cada biblioteca do Swift de que o aplicativo e/ou os testes dependem.
Adicione os destinos da biblioteca desta forma:
Adicione os destinos da biblioteca de aplicativos como dependências aos destinos do aplicativo.
Adicione os destinos de 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 de vários tipos de aplicativos diretamente no diretório de exemplos derules_apple. Exemplo:
Para saber mais sobre regras de build, consulte Regras da Apple para o Bazel.
Neste ponto, é uma boa ideia testar o build:
bazel build //:<application_target>
Etapa 4: (opcional) granularidade do build
Se o projeto for grande ou estiver crescendo, considere dividi-lo em vários pacotes do Bazel. Essa maior granularidade proporciona:
Maior incrementabilidade de builds,
Maior carregamento em paralelo de tarefas de build,
melhor manutenção para futuros usuários;
Melhor controle sobre a visibilidade do código-fonte nos destinos e pacotes. Isso evita problemas, como bibliotecas que contêm detalhes de implementação vazando para APIs públicas.
Dicas para detalhar o projeto:
Coloque cada biblioteca no próprio pacote do Bazel. Comece com aqueles que exigem o menor número de dependências e vá avançando na árvore de dependências.
À medida que você adiciona arquivos
BUILD
e especifica destinos, adicione esses novos destinos aos atributosdeps
dos destinos que dependem deles.A função
glob()
não ultrapassa os limites do pacote. Portanto, à medida que o número de pacotes aumenta, os arquivos correspondentes porglob()
diminuem.Ao adicionar um arquivo
BUILD
a um diretóriomain
, adicione também um arquivoBUILD
ao diretóriotest
correspondente.Aplique limites de visibilidade íntegros nos pacotes.
Crie o projeto após cada mudança importante nos arquivos
BUILD
e 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 origens dos erros ocorridos.
Exemplo:
bazel build //:my-target
Etapa 6: gerar o projeto do Xcode com rules_xcodeproj
Ao criar com o Bazel, os arquivos WORKSPACE
e BUILD
se tornam a fonte
da verdade sobre o build. Para informar isso, gere um projeto Xcode compatível com Bazel usando rules_xcodeproj.
Solução de problemas
Os erros do Bazel podem surgir quando ele fica dessincronizado com a versão selecionada do Xcode, como quando você aplica uma atualização. Se você estiver enfrentando erros com o Xcode, veja algumas opções. Por exemplo: "A versão do Xcode precisa ser especificada para usar uma CROSSTOOL".
Execute o Xcode manualmente e aceite os Termos e Condições.
Use o 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
.