Introdução
Novo no Bazel? Você está no lugar certo. Siga este tutorial do Primeiro build para um introdução simplificada ao uso do Bazel. Este tutorial define termos-chave conforme eles são usadas no contexto do Bazel e mostra os conceitos básicos da estrutura do de desenvolvimento de software. Começando com as ferramentas de que precisa, você criará e executará três projetos com complexidade cada vez maior e aprender como e por que eles se tornam mais complexos.
O Bazel é um sistema de build que oferece suporte a builds em várias linguagens, este tutorial usa um projeto C++ como exemplo e fornece as diretrizes e o fluxo gerais que se aplicam à maioria dos idiomas.
Tempo estimado de conclusão: 30 minutos.
Pré-requisitos
Comece instalando o Bazel, caso ainda não tenha feito isso. já. Este tutorial usa o Git para controle de origem. Portanto, para melhores resultados, instale Git (em inglês).
Em seguida, recupere o projeto de amostra no repositório do GitHub do Bazel executando o na ferramenta de linha de comando de sua preferência:
git clone https://github.com/bazelbuild/examples
O projeto de exemplo para este tutorial está no examples/cpp-tutorial
diretório.
Confira como está a estrutura:
examples
└── cpp-tutorial
├──stage1
│ ├── main
│ │ ├── BUILD
│ │ └── hello-world.cc
│ └── MODULE.bazel
├──stage2
│ ├── main
│ │ ├── BUILD
│ │ ├── hello-world.cc
│ │ ├── hello-greet.cc
│ │ └── hello-greet.h
│ └── MODULE.bazel
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── MODULE.bazel
Há três conjuntos de arquivos, cada um representando um estágio neste tutorial. Na primeira etapa, você cria um único destino que reside em um único pacote. Na segunda etapa, você criar um binário e uma biblioteca com um único pacote. Na terceira e última você vai criar um projeto com vários pacotes e criá-lo com vários destinos.
Resumo: introdução
Ao instalar o Bazel (e o Git) e clonar o repositório deste tutorial, você vai criou a base para sua primeira compilação com o Bazel. Continuar para a próxima para definir alguns termos e configurar sua workspace.
Primeiros passos
Antes de criar um projeto, é preciso configurar o espaço de trabalho dele. Um espaço de trabalho é um diretório que contém os arquivos de origem do seu projeto e as saídas de compilação do Bazel. Ela também contém estes arquivos importantes:
- O arquivo
MODULE.bazel
, que identifica o diretório e o conteúdo como um espaço de trabalho do Bazel e reside na raiz do diretório do projeto. na estrutura dos preços. É também onde você especifica as dependências externas. - Um ou mais
BUILD
arquivos, que informam ao Bazel como criar diferentes partes do projeto. Um diretório dentro da espaço de trabalho que contém um arquivoBUILD
é uma package (em inglês). Mais sobre pacotes mais adiante neste tutorial.
Em projetos futuros, para designar um diretório como um espaço de trabalho do Bazel, crie um
arquivo vazio chamado MODULE.bazel
nesse diretório. Para os fins deste
tutorial, um arquivo MODULE.bazel
já está presente em cada estágio.
Entenda o arquivo BUILD
Um arquivo BUILD
contém vários tipos diferentes de instruções para o Bazel. Cada
O arquivo BUILD
requer pelo menos um
regra como um conjunto de instruções,
que informa ao Bazel como criar as saídas desejadas, como binários executáveis
ou bibliotecas. Cada instância de uma regra de build no arquivo BUILD
é chamada de
target e aponta para um destino
de arquivos de origem e
dependências. Um alvo pode
também apontar para outros alvos.
Observe o arquivo BUILD
no diretório cpp-tutorial/stage1/main
:
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)
No nosso exemplo, o destino hello-world
instancia a biblioteca
cc_binary
regra. A regra
diz ao Bazel para criar um binário executável independente a partir da
hello-world.cc
> arquivo de origem sem dependências.
Resumo: introdução
Agora você conhece alguns termos-chave e o que eles significam no contexto neste projeto e ao Bazel em geral. Na próxima seção, você vai criar e testar Etapa 1 do projeto.
Estágio 1: destino único, pacote único
É hora de criar a primeira parte do projeto. Para uma referência visual, a da seção do Estágio 1 do projeto é:
examples
└── cpp-tutorial
└──stage1
├── main
│ ├── BUILD
│ └── hello-world.cc
└── MODULE.bazel
Execute o seguinte comando para mover para o diretório cpp-tutorial/stage1
:
cd cpp-tutorial/stage1
Depois execute:
bazel build //main:hello-world
No rótulo de destino, a parte //main:
é o local do arquivo BUILD
.
em relação à raiz do espaço de trabalho, e hello-world
é o nome do destino no
no arquivo BUILD
.
O Bazel produz algo parecido com isto:
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 2.267s, Critical Path: 0.25s
Você acabou de criar seu primeiro destino do Bazel. O Bazel coloca as saídas de build na
bazel-bin
na raiz do espaço de trabalho.
Agora teste seu binário recém-criado, que é:
bazel-bin/main/hello-world
Isso resulta em um "Hello world
" exibido mensagem.
Este é o gráfico de dependências do Estágio 1:
Resumo: etapa 1
Agora que você concluiu sua primeira compilação, tem uma ideia básica de como é estruturada. Na etapa seguinte, você vai aumentar a complexidade, outra meta.
Estágio 2: vários destinos de criação
Embora um único destino seja suficiente para projetos pequenos, é recomendável dividir projetos maiores em vários destinos e pacotes. Isso permite um processamento rápido ou seja, o Bazel apenas recria o que foi alterado e acelera seus builds criando várias partes de um projeto de uma só vez. Essa etapa adiciona um destino e o próximo adiciona um pacote.
Este é o diretório com que você está trabalhando para o Estágio 2:
├──stage2
│ ├── main
│ │ ├── BUILD
│ │ ├── hello-world.cc
│ │ ├── hello-greet.cc
│ │ └── hello-greet.h
│ └── MODULE.bazel
Observe o arquivo BUILD
no diretório cpp-tutorial/stage2/main
:
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
hdrs = ["hello-greet.h"],
)
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
":hello-greet",
],
)
Com esse arquivo BUILD
, o Bazel cria primeiro a biblioteca hello-greet
(usando
cc_library
do Bazel integrado
regra), o método
Binário hello-world
. O atributo deps
no destino hello-world
informa
Bazel de que a biblioteca hello-greet
é necessária para criar o hello-world
binário.
Antes de criar essa nova versão do projeto, é preciso mudar
diretórios, alternando para o diretório cpp-tutorial/stage2
executando:
cd ../stage2
Agora você pode criar o novo binário usando o seguinte comando conhecido:
bazel build //main:hello-world
Mais uma vez, o Bazel produz algo parecido com isto:
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 2.399s, Critical Path: 0.30s
Agora você pode testar seu binário recém-criado, que retorna outro "Hello
world
":
bazel-bin/main/hello-world
Se você agora modificar hello-greet.cc
e recriar o projeto, somente o Bazel
recompila esse arquivo.
No gráfico de dependências, é possível notar que hello-world
depende de um
entrada extra chamada hello-greet
:
Resumo: etapa 2
Você criou o projeto com dois destinos. O build de destino hello-world
um arquivo de origem e depende de outro destino (//main:hello-greet
), que
cria dois arquivos de origem adicionais. Na próxima seção, ir além
e adicionar outro pacote.
Estágio 3: vários pacotes
A próxima etapa adiciona outra camada de complicação e cria um projeto com
vários pacotes. Dê uma olhada na estrutura e no conteúdo
Diretório cpp-tutorial/stage3
:
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── MODULE.bazel
Agora há dois subdiretórios, e cada um contém um BUILD
. Portanto, para o Bazel, o espaço de trabalho agora contém dois pacotes: lib
e
main
.
Dê uma olhada no arquivo lib/BUILD
:
cc_library(
name = "hello-time",
srcs = ["hello-time.cc"],
hdrs = ["hello-time.h"],
visibility = ["//main:__pkg__"],
)
No arquivo main/BUILD
:
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
hdrs = ["hello-greet.h"],
)
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
":hello-greet",
"//lib:hello-time",
],
)
O destino hello-world
no pacote principal depende do destino hello-time
no pacote lib
(por isso o rótulo de destino //lib:hello-time
): o Bazel sabe
pelo atributo deps
. Isso se reflete no arquivo de
gráfico:
Para que o build tenha êxito, defina o destino //lib:hello-time
em lib/BUILD
.
explicitamente visível para destinos em main/BUILD
usando o atributo de visibilidade.
Isso ocorre porque, por padrão, só são visíveis para outros destinos no mesmo
BUILD
. O Bazel usa a visibilidade do destino para evitar problemas, como bibliotecas
com detalhes de implementação que vazam para APIs públicas.
Agora crie essa versão final do projeto. Mudar para cpp-tutorial/stage3
executando o seguinte:
cd ../stage3
Mais uma vez, execute o seguinte comando:
bazel build //main:hello-world
O Bazel produz algo parecido com isto:
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 0.167s, Critical Path: 0.00s
Agora, teste o último binário deste tutorial para uma mensagem Hello world
final:
bazel-bin/main/hello-world
Resumo: etapa 3
Você criou o projeto como dois pacotes com três destinos e entendeu as dependências entre elas, o que capacita você a avançar e criar projetos projetos com o Bazel. Na próxima seção, saiba como continuar Jornada do Bazel.
Próximas etapas
Você concluiu seu primeiro build básico com o Bazel, mas esse é só o começar. Confira mais alguns recursos para continuar aprendendo com o Bazel:
- Para manter o foco em C++, leia sobre o uso comum de build em C++ casos de uso diferentes.
- Para começar a criar outros aplicativos com o Bazel, consulte a tutoriais para Java, Android app ou iOS aplicativo.
- Para saber mais sobre como trabalhar com repositórios locais e remotos, leia sobre dependências externas.
- Saiba mais sobre as outras regras do Bazel nesta referência. guia.
Boa construção!