Tutorial do Bazel: criar um projeto em C++

Informar um problema Mostrar fonte Por noite · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

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 ferramenta 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, para que você tenha os melhores resultados instale o Git como muito bem.

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 diretório examples/cpp-tutorial.

Confira abaixo como ele está 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 um estágio neste tutorial. Na primeira etapa, 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 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 seu espaço de trabalho.

Primeiros passos

Configurar o espaço de trabalho

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 WORKSPACE file , 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.
  • um ou mais BUILD files , que informam ao Bazel como criar diferentes partes do projeto. Um no espaço de trabalho que contém um arquivo BUILD é 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 este 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. Informações mais detalhadas sobre as regras do espaço de trabalho podem podem ser encontradas neste guia.

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 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 na O arquivo BUILD é chamado de destino. e aponta para um conjunto específico de arquivos de origem e dependências. Um alvo também pode 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 rule. 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ê 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
       └── WORKSPACE

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

O resultado será a mensagem "Hello world" exibida.

Este é o gráfico de dependência do Estágio 1:

O gráfico de dependência de hello-world exibe um único destino com um único arquivo de origem.

Resumo: etapa 1

Agora que concluiu sua primeira compilação, você tem uma ideia básica de como uma está estruturada. Na etapa seguinte, você vai aumentar a complexidade acrescentando alvo.

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 o cria 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, é 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ê 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:

O gráfico de dependência de "hello-world" mostra as alterações na estrutura após a modificação do arquivo.

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. Confira abaixo a estrutura e o conteúdo da 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 (por isso o rótulo de destino //lib:hello-time): o Bazel sabe pelo atributo deps. Isso se reflete no arquivo de gráfico:

O gráfico de dependência de "hello-world" mostra como o destino no pacote principal depende do destino no pacote "lib".

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:

Boa construção!