כאן ניתן למצוא חלק ממקרי השימוש הנפוצים ביותר לבניית פרויקט C++ עם Bazel. אם עדיין לא עשיתם זאת, כדאי להתחיל לבנות פרויקטים עם C++ עם Bazel על ידי השלמת המדריך מבוא לבזל: בניית פרויקט C++.
אפשר למצוא מידע נוסף על קובצי כותרת מסוג cc_library ו-hdrs בכתובת cc_library.
הכללה של קבצים מרובים ביעד
ניתן לכלול כמה קבצים ביעד אחד באמצעות glob. למשל:
cc_library(
name = "build-all-the-files",
srcs = glob(["*.cc"]),
hdrs = glob(["*.h"]),
)
עם היעד הזה, Bazel תבנה את כל הקבצים ש-.cc
ו-.h
היא מוצאת באותה ספרייה כמו קובץ BUILD
שמכיל את היעד הזה (לא כולל ספריות משנה).
השימוש ברכיבים עקיפים כולל
אם קובץ כולל כותרת, הכלל הזה צריך לשמש כמקור (כלומר,
עריכת הקובץ במאפיינים srcs
, hdrs
, או textual_hdrs
) על כלל הספרייה של הכותרת הכלולה. לעומת זאת, יש לציין
תלויות ישירות רק כיחסי תלות. לדוגמה, נניח ש-sandwich.h
כולל את bread.h
ואת bread.h
כולל את flour.h
. sandwich.h
לא כולל את flour.h
(מי רוצה קמח בסנדוויץ'?), כך שהקובץ
BUILD
ייראה כך:
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"],
)
כאן, ספריית sandwich
תלויה בספריית bread
, שתלויה בספרייה של flour
.
מתבצעת הוספה של נתיבי הכללה
לפעמים אינך יכול (או לא רוצה) לכלול שורשים בסביבת העבודה הבסיסית. לספריות קיימות כבר יכולה להיות ספרייה הכללה שאינה תואמת לנתיב שלהן בסביבת העבודה שלכם. לדוגמה, נניח שיש לך את מבנה הספרייה הבא:
└── my-project
├── legacy
│ └── some_lib
│ ├── BUILD
│ ├── include
│ │ └── some_lib.h
│ └── some_lib.cc
└── WORKSPACE
Bazel תצפה ש-some_lib.h
ייכלל כ-legacy/some_lib/include/some_lib.h
, אבל נניח ש-some_lib.cc
כולל את
"some_lib.h"
. כדי שהנתיב יכלול נתיב חוקי,
יהיה על legacy/some_lib/BUILD
לציין שהספרייה some_lib/include
היא ספריית הכללה:
cc_library(
name = "some_lib",
srcs = ["some_lib.cc"],
hdrs = ["include/some_lib.h"],
copts = ["-Ilegacy/some_lib/include"],
)
זוהי אפשרות שימושית במיוחד עבור יחסי תלות חיצוניים, מפני שקובצי הכותרת שלהם
צריכים להיכלל בקידומת /
.
כולל ספריות חיצוניות
נניח שאתם משתמשים ב-Google Test.
תוכל להשתמש באחת מפונקציות המאגר בקובץ WORKSPACE
כדי להוריד את בדיקת Google ולהפוך אותה לזמינה במאגר שלך:
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",
)
לאחר מכן יש ליצור gtest.BUILD
, קובץ BUILD
המשמש להידור של בדיקת Google.
לבדיקה של Google יש כמה דרישות "מיוחדות" שהופכות את הכלל cc_library
למורכבות יותר:
googletest-release-1.10.0/src/gtest-all.cc
#include
כל שאר הקבצים ב-googletest-release-1.10.0/src/
: יש להחריג את הקובץ מההידור כדי למנוע שגיאות בקישור לסמלים כפולים.היא משתמשת בקובצי כותרת שהם יחסיים לספרייה
googletest-release-1.10.0/include/
("gtest/gtest.h"
), לכן עליך להוסיף את הספרייה לנתיבי ההכללה.הקישור חייב להתבצע ב-
pthread
, לכן יש להוסיף אותו כ-linkopt
.
לכן הכלל האחרון נראה כך:
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"],
)
משהו קצת מבולגן: התחילית של googletest-release-1.10.0
היא תוצר נוסף של מבנה הארכיון. ניתן להוסיף http_archive
לקידומת הזו
על ידי הוספת המאפיין 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",
)
אז gtest.BUILD
ייראה כך:
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"],
)
עכשיו כללי cc_
תלויים ב-@gtest//:main
.
כתיבה והפעלה של בדיקות C++
לדוגמה, אפשר ליצור בדיקה של ./test/hello-test.cc
, למשל:
#include "gtest/gtest.h"
#include "main/hello-greet.h"
TEST(HelloTest, GetGreet) {
EXPECT_EQ(get_greet("Bazel"), "Hello Bazel");
}
לאחר מכן, יוצרים קובץ ./test/BUILD
לבדיקות:
cc_test(
name = "hello-test",
srcs = ["hello-test.cc"],
copts = ["-Iexternal/gtest/include"],
deps = [
"@gtest//:main",
"//main:hello-greet",
],
)
כדי שhello-greet
יהיה גלוי ל-hello-test
, עליך להוסיף את
"//test:__pkg__",
למאפיין visibility
ב-./main/BUILD
.
עכשיו אפשר להשתמש ב-bazel test
כדי להריץ את הבדיקה.
bazel test test:hello-test
זה מפיק את הפלט הבא:
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.
הוספת יחסי תלות בספריות שנוצרו מראש
אם ברצונך להשתמש בספרייה שיש לך רק גרסה מגובשת (לדוגמה, כותרות וקובץ .so
), יש לעטוף אותה בכלל של cc_library
:
cc_library(
name = "mylib",
srcs = ["mylib.so"],
hdrs = ["mylib.h"],
)
באופן כזה, יעדי C++ אחרים בסביבת העבודה שלך עשויים להיות תלויים בכלל הזה.