Di sini, Anda akan menemukan beberapa kasus penggunaan paling umum untuk mem-build project C++ dengan Bazel. Jika Anda belum melakukannya, mulailah membuat project C++ dengan Bazel dengan menyelesaikan tutorial Pengantar Bazel: Mem-build Project C++.
Untuk informasi tentang file header cc_library dan hdrs, lihat cc_library.
Menyertakan beberapa file dalam target
Anda dapat menyertakan beberapa file dalam satu target dengan glob. Contoh:
cc_library(
name = "build-all-the-files",
srcs = glob(["*.cc"]),
hdrs = glob(["*.h"]),
)
Dengan target ini, Bazel akan mem-build semua file .cc
dan .h
yang ditemukan di
direktori yang sama dengan file BUILD
yang berisi target ini (tidak termasuk
subdirektori).
Menggunakan transitif mencakup
Jika file menyertakan header, aturan apa pun dengan file tersebut sebagai sumber (yaitu, memiliki file tersebut di atribut srcs
, hdrs
, atau textual_hdrs
) harus bergantung pada aturan library header yang disertakan. Sebaliknya, hanya dependensi
langsung yang harus ditentukan sebagai dependensi. Misalnya, sandwich.h
menyertakan bread.h
dan bread.h
menyertakan flour.h
. sandwich.h
tidak menyertakan flour.h
(siapa yang ingin membuat tepung di sandwichnya?), maka file BUILD
akan terlihat seperti ini:
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"],
)
Di sini, library sandwich
bergantung pada library bread
, yang bergantung
pada library flour
.
Menambahkan jalur penyertaan
Terkadang Anda tidak dapat (atau tidak ingin) melakukan root pada jalur di root ruang kerja. Library yang ada mungkin sudah memiliki direktori include yang tidak cocok dengan jalurnya di ruang kerja Anda. Misalnya, anggaplah Anda memiliki struktur direktori berikut:
└── my-project
├── legacy
│ └── some_lib
│ ├── BUILD
│ ├── include
│ │ └── some_lib.h
│ └── some_lib.cc
└── WORKSPACE
Bazel akan mengharapkan some_lib.h
disertakan sebagai
legacy/some_lib/include/some_lib.h
, tetapi anggaplah some_lib.cc
menyertakan
"some_lib.h"
. Untuk membuat jalur penyertaan tersebut valid,
legacy/some_lib/BUILD
harus menentukan bahwa direktori some_lib/include
adalah direktori yang disertakan:
cc_library(
name = "some_lib",
srcs = ["some_lib.cc"],
hdrs = ["include/some_lib.h"],
copts = ["-Ilegacy/some_lib/include"],
)
Hal ini sangat berguna untuk dependensi eksternal, karena file header-nya
harus disertakan dengan awalan /
.
Menyertakan library eksternal
Misalnya Anda menggunakan Uji Google.
Anda dapat menggunakan salah satu fungsi repositori dalam file WORKSPACE
untuk
mendownload Google Test dan menyediakannya di repositori:
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",
)
Lalu buat gtest.BUILD
, file BUILD
yang digunakan untuk mengompilasi Google Test.
Google Test memiliki beberapa persyaratan "khusus" yang membuat aturan cc_library
-nya
lebih rumit:
googletest-release-1.10.0/src/gtest-all.cc
#include
menyimpan semua file lain digoogletest-release-1.10.0/src/
: mengecualikannya dari kompilasi untuk mencegah error link pada simbol duplikat.Atribut ini menggunakan file header yang relatif terhadap direktori
googletest-release-1.10.0/include/
("gtest/gtest.h"
), sehingga Anda harus menambahkan direktori tersebut ke jalur yang disertakan.Link harus ditautkan di
pthread
, jadi tambahkan sebagailinkopt
.
Oleh karena itu, aturan akhir terlihat seperti ini:
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"],
)
Hal ini agak berantakan: semuanya diawali dengan googletest-release-1.10.0
sebagai produk sampingan dari struktur arsip. Anda dapat membuat http_archive
menghapus
awalan ini dengan menambahkan atribut 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",
)
Kemudian, gtest.BUILD
akan terlihat seperti ini:
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"],
)
Sekarang aturan cc_
dapat bergantung pada @gtest//:main
.
Menulis dan menjalankan pengujian C++
Misalnya, Anda dapat membuat ./test/hello-test.cc
pengujian, seperti:
#include "gtest/gtest.h"
#include "main/hello-greet.h"
TEST(HelloTest, GetGreet) {
EXPECT_EQ(get_greet("Bazel"), "Hello Bazel");
}
Kemudian buat file ./test/BUILD
untuk pengujian Anda:
cc_test(
name = "hello-test",
srcs = ["hello-test.cc"],
copts = ["-Iexternal/gtest/include"],
deps = [
"@gtest//:main",
"//main:hello-greet",
],
)
Agar hello-greet
terlihat oleh hello-test
, Anda harus menambahkan
"//test:__pkg__",
ke atribut visibility
di ./main/BUILD
.
Sekarang Anda dapat menggunakan bazel test
untuk menjalankan pengujian.
bazel test test:hello-test
Ini menghasilkan output berikut:
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.
Menambahkan dependensi pada library yang telah dikompilasi sebelumnya
Jika ingin menggunakan library yang hanya Anda miliki versi yang dikompilasi (misalnya
header dan file .so
), gabungkan ke aturan cc_library
:
cc_library(
name = "mylib",
srcs = ["mylib.so"],
hdrs = ["mylib.h"],
)
Dengan cara ini, target C++ lainnya di ruang kerja dapat bergantung pada aturan ini.