Bazel ile C++ projeleri oluşturmanın en yaygın kullanım alanlarından bazılarını burada bulabilirsiniz. Henüz yapmadıysanız Bazel'e Giriş: C++ Projesi Oluşturma eğitimini tamamlayarak 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"]),
)
Bazel, bu hedefi içeren BUILD
dosyasıyla aynı dizinde bulduğu tüm .cc
ve .h
dosyalarını (alt dizinler hariç) bu hedefle derleyecektir.
Geçişli dahil etme işlemlerini kullanma
Bir dosya üstbilgi içeriyorsa kaynak olarak bu dosyayı içeren tüm kurallar (yani srcs
, hdrs
veya textual_hdrs
özelliğinde bu dosyanın bulunduğu kurallar), dahil edilen üstbilginin kitaplık kuralına bağlı olmalıdır. Buna karşılık, bağımlılık olarak yalnızca doğrudan bağımlılıkların belirtilmesi gerekir. Örneğin, sandwich.h
'ün bread.h
'ü ve bread.h
'ün flour.h
'yi içerdiğini varsayalım. sandwich.h
, flour.h
içermez (sandviçinde un isteyen var mı?). Bu nedenle BUILD
dosyası şöyle görünür:
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ığı, flour
kitaplığına bağlı olan bread
kitaplığına bağlıdır.
Dahil etme yolları ekleme
Bazen çalışma alanı kökünde kök dahil etme yollarını kullanamazsınız (veya kullanmak istemezsiniz). Mevcut kitaplıklarda, Workspace'teki yoluyla eşleşmeyen bir dahil dizini olabilir. Örneğin, aşağıdaki dizin yapısını kullandığınızı varsayalım:
└── my-project
├── legacy
│ └── some_lib
│ ├── BUILD
│ ├── include
│ │ └── some_lib.h
│ └── some_lib.cc
└── WORKSPACE
Bazel, some_lib.h
'ün legacy/some_lib/include/some_lib.h
olarak dahil edilmesini bekler ancak some_lib.cc
'de "some_lib.h"
olduğunu varsayalım. Bu dahil etme yolunun geçerli olabilmesi için legacy/some_lib/BUILD
'ün, some_lib/include
dizininin bir dahil etme dizini olduğunu belirtmesi gerekir:
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ıklarda kullanışlıdır. Aksi takdirde, başlık dosyaları /
ön ekiyle eklenmelidir.
Harici kitaplıklar ekleme
Google Testi'ni kullandığınızı varsayalım.
Google Test'i indirip deponuzda kullanılabilir hale getirmek için WORKSPACE
dosyasındaki depolama 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 BUILD
dosyası olan gtest.BUILD
dosyasını oluşturun.
Google Test'in cc_library
kuralını daha karmaşık hale getiren birkaç "özel" koşulu vardır:
googletest-release-1.10.0/src/gtest-all.cc
#include
s diğer tüm dosyalarıgoogletest-release-1.10.0/src/
: Yinelenen simgelerle ilgili bağlantı hatalarını önlemek için bu dosyayı derlemeden hariç tutun.googletest-release-1.10.0/include/
dizine ("gtest/gtest.h"
) göreli başlık dosyaları kullandığından bu dizini dahil edilecek yollara eklemeniz gerekir.pthread
'e bağlanması gerektiği için bu öğeyilinkopt
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 durum biraz karmaşıktır: 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 bu ön eki kaldırmasını sağlayabilirsiniz:
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, şu 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
'ü hello-test
için görünür hale getirmek istiyorsanız ./main/BUILD
'teki visibility
özelliğine "//test:__pkg__",
eklemeniz gerekir.
Artık testi çalıştırmak için bazel test
simgesini kullanabilirsiniz.
bazel test test:hello-test
Bu işlem aşağıdaki çıkışı oluşturur:
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ıklar ekleme
Yalnızca derlenmiş bir sürümüne sahip olduğunuz bir kitaplığı (ör. üstbilgiler ve bir .so
dosyası) kullanmak istiyorsanız bu kitaplığı 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.