Aqui você encontrará alguns dos casos de uso mais comuns para a criação de projetos C++ com o Bazel. Comece a criar em C++, caso ainda não tenha feito isso. projetos com o Bazel concluindo o tutorial Introdução ao Bazel: criar um projeto C++.
Para obter informações sobre os arquivos de cabeçalho cc_library e hdrs, consulte cc_library.
Como incluir vários arquivos em um destino
Você pode incluir vários arquivos em um único destino com glob. Exemplo:
cc_library(
name = "build-all-the-files",
srcs = glob(["*.cc"]),
hdrs = glob(["*.h"]),
)
Com esse destino, o Bazel cria todos os arquivos .cc
e .h
que encontrar no
mesmo diretório do arquivo BUILD
que contém o destino (excluindo
subdiretórios).
Usar inclusões transitivas
Se um arquivo incluir um cabeçalho, todas as regras com esse arquivo como origem (ou seja,
ter esse arquivo no atributo srcs
, hdrs
ou textual_hdrs
) deve
dependem da regra da biblioteca do cabeçalho incluído. Por outro lado, apenas os clientes diretos
as dependências precisam ser especificadas como dependências. Por exemplo, suponha
sandwich.h
inclui bread.h
e bread.h
inclui flour.h
. sandwich.h
não inclui flour.h
(quem quer farinha no sanduíche?), então BUILD
ficaria assim:
cc_library(
name = "sandwich",
srcs = ["sandwich.cc"],
hdrs = ["sandwich.h"],
deps = [":bread"],
)
cc_library(
name = "bread",
srcs = ["bread.cc"],
hdrs = ["bread.h"],
deps = [":flour"],
)
cc_library(
name = "flour",
srcs = ["flour.cc"],
hdrs = ["flour.h"],
)
Aqui, a biblioteca sandwich
depende da biblioteca bread
, que depende
na biblioteca flour
.
Como adicionar caminhos de inclusão
Às vezes, não é possível (ou não quer) caminhos de inclusão raiz no espaço de trabalho. raiz. As bibliotecas existentes podem já ter um diretório de inclusão que não corresponder ao caminho dela no espaço de trabalho. Por exemplo, suponha que você tenha o seguinte do diretório atual:
└── my-project
├── legacy
│ └── some_lib
│ ├── BUILD
│ ├── include
│ │ └── some_lib.h
│ └── some_lib.cc
└── WORKSPACE
O Bazel espera que some_lib.h
seja incluído como
legacy/some_lib/include/some_lib.h
, mas suponha que some_lib.cc
inclua
"some_lib.h"
. Para tornar esse caminho de inclusão válido,
O legacy/some_lib/BUILD
vai precisar especificar que o some_lib/include
é um diretório de inclusão:
cc_library(
name = "some_lib",
srcs = ["some_lib.cc"],
hdrs = ["include/some_lib.h"],
copts = ["-Ilegacy/some_lib/include"],
)
Isso é muito útil para dependências externas, já que os arquivos principais
precisam ser incluídos com um prefixo /
.
Como incluir bibliotecas externas
Vamos supor que você esteja usando o Google Test.
É possível usar uma das funções de repositório no arquivo WORKSPACE
para
Baixe o Google Test e disponibilize-o no repositório:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "gtest",
url = "https://github.com/google/googletest/archive/release-1.10.0.zip",
sha256 = "94c634d499558a76fa649edb13721dce6e98fb1e7018dfaeba3cd7a083945e91",
build_file = "@//:gtest.BUILD",
)
Em seguida, crie gtest.BUILD
, um arquivo BUILD
usado para compilar o teste do Google.
O Google Test tem várias funções "especiais" requisitos que tornam a regra cc_library
mais complicada:
googletest-release-1.10.0/src/gtest-all.cc
#include
s todos os outros emgoogletest-release-1.10.0/src/
: exclua-o da compilar para evitar erros de link para símbolos duplicados.Ele usa arquivos de cabeçalho relativos à
googletest-release-1.10.0/include/
("gtest/gtest.h"
), então é necessário adicionar esse diretório aos caminhos de inclusão.É necessário vincular a conta em
pthread
. Portanto, adicione-a comolinkopt
.
Portanto, a regra final ficará assim:
cc_library(
name = "main",
srcs = glob(
["googletest-release-1.10.0/src/*.cc"],
exclude = ["googletest-release-1.10.0/src/gtest-all.cc"]
),
hdrs = glob([
"googletest-release-1.10.0/include/**/*.h",
"googletest-release-1.10.0/src/*.h"
]),
copts = [
"-Iexternal/gtest/googletest-release-1.10.0/include",
"-Iexternal/gtest/googletest-release-1.10.0"
],
linkopts = ["-pthread"],
visibility = ["//visibility:public"],
)
Isso é um pouco confuso: tudo é prefixado com googletest-release-1.10.0
.
como subproduto da estrutura do arquivo. Você pode fazer http_archive
faixa
esse prefixo adicionando o atributo strip_prefix
:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "gtest",
url = "https://github.com/google/googletest/archive/release-1.10.0.zip",
sha256 = "94c634d499558a76fa649edb13721dce6e98fb1e7018dfaeba3cd7a083945e91",
build_file = "@//:gtest.BUILD",
strip_prefix = "googletest-release-1.10.0",
)
Então, gtest.BUILD
ficaria assim:
cc_library(
name = "main",
srcs = glob(
["src/*.cc"],
exclude = ["src/gtest-all.cc"]
),
hdrs = glob([
"include/**/*.h",
"src/*.h"
]),
copts = ["-Iexternal/gtest/include"],
linkopts = ["-pthread"],
visibility = ["//visibility:public"],
)
Agora, as regras cc_
podem depender de @gtest//:main
.
Como programar e executar testes em C++
Por exemplo, você pode criar um teste ./test/hello-test.cc
, como:
#include "gtest/gtest.h"
#include "main/hello-greet.h"
TEST(HelloTest, GetGreet) {
EXPECT_EQ(get_greet("Bazel"), "Hello Bazel");
}
Em seguida, crie o arquivo ./test/BUILD
para os testes:
cc_test(
name = "hello-test",
srcs = ["hello-test.cc"],
copts = ["-Iexternal/gtest/include"],
deps = [
"@gtest//:main",
"//main:hello-greet",
],
)
Para tornar o app hello-greet
visível para o app hello-test
, adicione
"//test:__pkg__",
para o atributo visibility
em ./main/BUILD
.
Agora, você pode usar bazel test
para executar o teste.
bazel test test:hello-test
Isso produz a seguinte saída:
INFO: Found 1 test target...
Target //test:hello-test up-to-date:
bazel-bin/test/hello-test
INFO: Elapsed time: 4.497s, Critical Path: 2.53s
//test:hello-test PASSED in 0.3s
Executed 1 out of 1 tests: 1 test passes.
Como adicionar dependências em bibliotecas pré-compiladas
Se você quiser usar uma biblioteca da qual você só tem uma versão compilada (por
exemplo, cabeçalhos e um arquivo .so
) unem-o em uma regra cc_library
:
cc_library(
name = "mylib",
srcs = ["mylib.so"],
hdrs = ["mylib.h"],
)
Dessa forma, outros destinos C++ no seu espaço de trabalho podem depender dessa regra.