Introdução
Você não conhece o Bazel? Você está no lugar certo. Siga este tutorial de Primeiro build para uma 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 necessárias, você vai criar e executar três projetos com complexidade crescente e aprender como e por que eles ficam mais complexos.
Embora o Bazel seja um sistema de build que oferece suporte a builds em vários idiomas, 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, para que você tenha os melhores resultados instale o Git como muito bem.
Em seguida, extraia o projeto de exemplo do repositório do GitHub do Bazel executando o seguinte 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 diretório examples/cpp-tutorial
.
Confira abaixo como ele é estruturado:
examples
└── cpp-tutorial
├──stage1
│ ├── main
│ │ ├── BUILD
│ │ └── hello-world.cc
│ └── WORKSPACE
├──stage2
│ ├── main
│ │ ├── BUILD
│ │ ├── hello-world.cc
│ │ ├── hello-greet.cc
│ │ └── hello-greet.h
│ └── WORKSPACE
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── WORKSPACE
Há três conjuntos de arquivos, cada um representando uma etapa neste tutorial. No primeiro estágio, você cria um único destino que reside em um único pacote. Na segunda etapa, você você vai criar um binário e uma biblioteca com o mesmo pacote. Em na terceira e última etapa, você vai criar um projeto com vários pacotes e construí-lo com vários destinos.
Resumo: introdução
Ao instalar o Bazel (e o Git) e clonar o repositório para este tutorial, você estabeleceu a base para seu primeiro build com o Bazel. Continuar para a próxima para definir alguns termos e configurar seu espaço de trabalho.
Primeiros passos
Configurar o espaço de trabalho
Antes de criar um projeto, você precisa 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 build do Bazel. Ela também contém estes arquivos importantes:
- O
, que identifica o diretório e o conteúdo dele como um espaço de trabalho do Bazel e reside na raiz da estrutura de diretórios do projeto.WORKSPACE
file - Um ou mais
, que informam ao Bazel como criar diferentes partes do projeto. Um no espaço de trabalho que contém um arquivoBUILD
filesBUILD
é um 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 WORKSPACE
nesse diretório. Para os fins deste tutorial,
um arquivo WORKSPACE
já está presente em cada etapa.
OBSERVAÇÃO: quando o Bazel cria o projeto, todas as entradas precisam estar no no mesmo espaço de trabalho. Os arquivos em diferentes espaços de trabalho são independentes entre si, a menos que estejam vinculados. Confira informações mais detalhadas sobre as regras do espaço de trabalho neste guia.
Entenda o arquivo BUILD
Um arquivo BUILD
contém vários tipos diferentes de instruções para o Bazel. Cada
arquivo BUILD
requer pelo menos uma regra
como um conjunto de instruções, que informa ao Bazel como criar as saídas desejadas,
como bibliotecas ou binários executáveis. Cada instância de uma regra de build no
arquivo BUILD
é chamada de target
e aponta para um conjunto específico de arquivos de origem e dependências.
Um destino também pode apontar para outros destinos.
Confira 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 o cc_binary rule
integrado do Bazel.
Ela instrui o Bazel a criar um binário executável independente do
Arquivo de origem hello-world.cc
sem dependências.
Resumo: introdução
Agora você já conhece alguns termos importantes e o que eles significam no contexto deste projeto e do 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 estrutura da seção "Etapa 1" do projeto é:
examples
└── cpp-tutorial
└──stage1
├── main
│ ├── BUILD
│ └── hello-world.cc
└── WORKSPACE
Execute o seguinte 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 de destino 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 no
diretório bazel-bin
na raiz do
espaço de trabalho.
Agora teste o binário recém-criado, que é:
bazel-bin/main/hello-world
O resultado será a mensagem "Hello world
" exibida.
Confira o gráfico de dependência da fase 1:
Resumo: etapa 1
Agora que concluiu sua primeira compilação, você tem uma ideia básica de como uma está estruturada. Na próxima etapa, você vai aumentar a complexidade adicionando outro destino.
Fase 2: vários destinos de build
Embora um único destino seja suficiente para projetos pequenos, é recomendável dividir projetos maiores em vários destinos e pacotes. Isso permite builds incrementais rápidos, ou seja, o Bazel só recria o que mudou, 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
│ └── WORKSPACE
Observe o arquivo BUILD
abaixo 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 o cc_library rule
integrado do Bazel),
depois o binário hello-world
. O atributo deps
no
o destino hello-world
informa ao Bazel que o hello-greet
é necessária para criar o binário hello-world
.
Antes de criar essa nova versão do projeto, você precisa mudar
de diretório, 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ê modificar hello-greet.cc
e recriar o projeto, o Bazel só fará a recompilação.
esse arquivo.
No gráfico de dependências, é possível notar que "hello-world" depende da as mesmas entradas de antes, mas a estrutura do build é diferente:
Resumo: fase 2
Você criou o projeto com dois destinos. O destino hello-world
cria
um arquivo de origem e depende de outro destino (//main:hello-greet
), que
cria dois arquivos de origem adicionais. Na próxima seção, vamos dar um passo adiante
e adicionar outro pacote.
Estágio 3: vários pacotes
Esta próxima etapa adiciona outra camada de complicação e cria um projeto com
vários pacotes. Confira abaixo a estrutura e o conteúdo 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
└── WORKSPACE
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
(daí o rótulo de destino //lib:hello-time
). O Bazel sabe
isso 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 a 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: fase 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 isso é apenas o começo. Confira mais alguns recursos para continuar aprendendo com o Bazel:
- Para continuar se concentrando em C++, leia sobre casos de uso comuns de build de C++.
- Para começar a criar outros aplicativos com o Bazel, consulte os tutoriais para Java, aplicativo Android, ou aplicativo iOS.
- Para saber mais sobre como trabalhar com repositórios locais e remotos, leia sobre dependências externas.
- Para saber mais sobre as outras regras do Bazel, consulte este guia de referência.
Boa construção!