Burada, Bazel ile C++ projeleri oluşturmaya yönelik en yaygın kullanım alanlarından bazılarını bulabilirsiniz. Henüz yapmadıysanız Introduction to Bazel: Build a C++ Project (Bazel'e Giriş: C++ Projesi Oluşturma) adlı eğitime katılarak Bazel ile C++ projeleri oluşturmaya başlayın.
cc_library ve hdrs üstbilgi dosyaları hakkında bilgi edinmek için cc_library başlıklı makaleyi inceleyin.
Bir hedefe birden fazla dosya ekleme
glob ile tek bir hedefe birden fazla dosya ekleyebilirsiniz. Örneğin:
cc_library(
name = "build-all-the-files",
srcs = glob(["*.cc"]),
hdrs = glob(["*.h"]),
)
Bu hedefle Bazel, bu hedefi içeren BUILD
dosyasıyla aynı dizinde bulduğu tüm .cc
ve .h
dosyalarını (alt dizinler hariç) oluşturur.
Geçişli dahil etme işlemlerini kullanma
Bir dosya üstbilgi içeriyorsa bu dosyayı kaynak olarak kullanan tüm kurallar (yani srcs
, hdrs
veya textual_hdrs
özelliğinde bu dosyanın bulunduğu kurallar) eklenen üstbilginin kitaplık kuralına bağlı olmalıdır. Buna karşılık, yalnızca doğrudan bağımlılıklar bağımlılık olarak belirtilmelidir. Örneğin, sandwich.h
'nın bread.h
'ı ve bread.h
'ın flour.h
'ı içerdiğini varsayalım. sandwich.h
içermiyor (sandviçinde un isteyen olur mu?), bu nedenle BUILD
dosyası şöyle görünür:flour.h
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"],
)
Burada sandwich
kitaplığı, bread
kitaplığına, bread
kitaplığı ise flour
kitaplığına bağlıdır.
Dahil etme yolları ekleme
Bazen yolları çalışma alanı köküne dahil edemezsiniz (veya dahil etmek istemezsiniz). Mevcut kitaplıklarda, çalışma alanınızdaki yoluyla eşleşmeyen bir include dizini olabilir. Örneğin, aşağıdaki dizin yapısına sahip olduğunuzu varsayalım:
└── my-project
├── legacy
│ └── some_lib
│ ├── BUILD
│ ├── include
│ │ └── some_lib.h
│ └── some_lib.cc
└── WORKSPACE
Bazel, some_lib.h
öğesinin legacy/some_lib/include/some_lib.h
olarak eklenmesini bekler ancak some_lib.cc
öğesinin "some_lib.h"
içerdiğini varsayalım. Bu include yolunun geçerli olması için legacy/some_lib/BUILD
, some_lib/include
dizininin bir include dizini olduğunu belirtmelidir:
cc_library(
name = "some_lib",
srcs = ["some_lib.cc"],
hdrs = ["include/some_lib.h"],
copts = ["-Ilegacy/some_lib/include"],
)
Bu, özellikle harici bağımlılıklar için kullanışlıdır. Aksi takdirde, bunların başlık dosyaları /
önekiyle birlikte eklenmelidir.
Harici kitaplıklar dahil
Google Test'i kullandığınızı varsayalım.
Google Test'i indirip deponuzda kullanılabilir hale getirmek için WORKSPACE
dosyasındaki depo işlevlerinden birini kullanabilirsiniz:
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",
)
Ardından, Google Test'i derlemek için kullanılan bir gtest.BUILD
BUILD
dosyası oluşturun.
Google Test'in, cc_library
kuralını daha karmaşık hale getiren çeşitli "özel" şartları vardır:
googletest-release-1.10.0/src/gtest-all.cc
#include
s all other files ingoogletest-release-1.10.0/src/
: exclude it from the compile to prevent link errors for duplicate symbols.googletest-release-1.10.0/include/
dizinine ("gtest/gtest.h"
) göre olan başlık dosyalarını kullandığından bu dizini include yollarına eklemeniz gerekir.pthread
ile bağlantı oluşturması gerekiyor. Bu nedenle,pthread
'yılinkopt
olarak ekleyin.
Bu nedenle, nihai kural şu şekilde görünür:
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"],
)
Bu biraz karmaşık bir durumdur: Arşivin yapısının bir yan ürünü olarak her şeyin önüne googletest-release-1.10.0
eklenir. strip_prefix
özelliğini ekleyerek http_archive
ön ekini kaldırabilirsiniz:
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",
)
Bu durumda gtest.BUILD
şöyle görünür:
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"],
)
Artık cc_
kuralları @gtest//:main
'e bağlı olabilir.
C++ testleri yazma ve çalıştırma
Örneğin, aşağıdaki gibi bir test ./test/hello-test.cc
oluşturabilirsiniz:
#include "gtest/gtest.h"
#include "main/hello-greet.h"
TEST(HelloTest, GetGreet) {
EXPECT_EQ(get_greet("Bazel"), "Hello Bazel");
}
Ardından, testleriniz için ./test/BUILD
dosyası oluşturun:
cc_test(
name = "hello-test",
srcs = ["hello-test.cc"],
copts = ["-Iexternal/gtest/include"],
deps = [
"@gtest//:main",
"//main:hello-greet",
],
)
hello-greet
özelliğinin hello-test
tarafından görünür olması için ./main/BUILD
içindeki visibility
özelliğine "//test:__pkg__",
eklemeniz gerekir.
Artık testi çalıştırmak için bazel test
kullanabilirsiniz.
bazel test test:hello-test
Bu işlem aşağıdaki çıkışı üretir:
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.
Önceden derlenmiş kitaplıklara bağımlılık ekleme
Yalnızca derlenmiş bir sürümüne sahip olduğunuz bir kitaplığı (örneğin, başlıklar ve bir .so
dosyası) kullanmak istiyorsanız bunu bir cc_library
kuralına sarın:
cc_library(
name = "mylib",
srcs = ["mylib.so"],
hdrs = ["mylib.h"],
)
Bu sayede, çalışma alanınızdaki diğer C++ hedefleri bu kurala bağlı olabilir.