Các trường hợp sử dụng bản dựng C++ phổ biến

Tại đây, bạn sẽ tìm thấy một số trường hợp sử dụng phổ biến nhất khi xây dựng dự án C++ bằng Bazel. Nếu bạn chưa làm như vậy, hãy bắt đầu xây dựng các dự án C++ bằng Bazel bằng cách hoàn tất phần hướng dẫn Giới thiệu về Bazel: Xây dựng dự án C++.

Để biết thông tin về tệp tiêu đề cc_library và hdrs, hãy xem phần cc_library.

Đưa nhiều tệp vào một mục tiêu

Bạn có thể đưa nhiều tệp vào một mục tiêu bằng glob. Ví dụ:

cc_library(
    name = "build-all-the-files",
    srcs = glob(["*.cc"]),
    hdrs = glob(["*.h"]),
)

Với mục tiêu này, Bazel sẽ tạo tất cả các tệp .cc.h mà nó tìm thấy trong cùng thư mục với tệp BUILD chứa mục tiêu này (ngoại trừ các thư mục con).

Sử dụng tính năng bao gồm bắc cầu

Nếu một tệp có chứa tiêu đề, thì mọi quy tắc có tệp đó làm nguồn (tức là có tệp đó trong thuộc tính srcs, hdrs hoặc textual_hdrs) sẽ phụ thuộc vào quy tắc thư viện của tiêu đề được đưa vào. Ngược lại, bạn chỉ cần chỉ định các phần phụ thuộc trực tiếp làm phần phụ thuộc. Ví dụ: giả sử sandwich.h bao gồm bread.hbread.h bao gồm flour.h. sandwich.h không bao gồm flour.h (ai muốn có bột mì trong bánh sandwich?), vì vậy, tệp BUILD sẽ có dạng như sau:

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"],
)

Ở đây, thư viện sandwich phụ thuộc vào thư viện bread, thư viện này phụ thuộc vào thư viện flour.

Thêm đường dẫn bao gồm

Đôi khi, bạn không thể (hoặc không muốn) đưa các đường dẫn vào thư mục gốc tại thư mục gốc của không gian làm việc. Các thư viện hiện có có thể đã có một thư mục bao gồm không khớp với đường dẫn của thư mục đó trong không gian làm việc của bạn. Ví dụ: giả sử bạn có cấu trúc thư mục sau:

└── my-project
    ├── legacy
    │   └── some_lib
    │       ├── BUILD
    │       ├── include
    │       │   └── some_lib.h
    │       └── some_lib.cc
    └── MODULE.bazel

Bazel dự kiến sẽ đưa some_lib.h vào dưới dạng legacy/some_lib/include/some_lib.h, nhưng giả sử some_lib.cc bao gồm "some_lib.h". Để đường dẫn bao gồm đó hợp lệ, legacy/some_lib/BUILD sẽ cần chỉ định rằng thư mục some_lib/include là thư mục bao gồm:

cc_library(
    name = "some_lib",
    srcs = ["some_lib.cc"],
    hdrs = ["include/some_lib.h"],
    copts = ["-Ilegacy/some_lib/include"],
)

Điều này đặc biệt hữu ích cho các phần phụ thuộc bên ngoài, vì tệp tiêu đề của các phần phụ thuộc đó phải được đi kèm với tiền tố /.

Bao gồm các thư viện bên ngoài

Giả sử bạn đang sử dụng Google Test {: .external}. Bạn có thể thêm phần phụ thuộc trên đó trong tệp MODULE.bazel để tải Google Test xuống và cung cấp trong kho lưu trữ:

bazel_dep(name = "googletest", version = "1.15.2")

Viết và chạy kiểm thử C++

Ví dụ: bạn có thể tạo một ./test/hello-test.cc kiểm thử, chẳng hạn như:

#include "gtest/gtest.h"
#include "main/hello-greet.h"

TEST(HelloTest, GetGreet) {
  EXPECT_EQ(get_greet("Bazel"), "Hello Bazel");
}

Sau đó, hãy tạo tệp ./test/BUILD cho các bài kiểm thử:

cc_test(
    name = "hello-test",
    srcs = ["hello-test.cc"],
    copts = [
      "-Iexternal/gtest/googletest/include",
      "-Iexternal/gtest/googletest",
    ],
    deps = [
        "@googletest//:main",
        "//main:hello-greet",
    ],
)

Để hello-test hiển thị hello-greet, bạn phải thêm "//test:__pkg__", vào thuộc tính visibility trong ./main/BUILD.

Bây giờ, bạn có thể sử dụng bazel test để chạy kiểm thử.

bazel test test:hello-test

Thao tác này sẽ tạo ra kết quả sau:

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.

Thêm phần phụ thuộc trên các thư viện được biên dịch trước

Nếu bạn muốn sử dụng một thư viện mà bạn chỉ có phiên bản đã biên dịch (ví dụ: tiêu đề và tệp .so), hãy gói thư viện đó trong quy tắc cc_library:

cc_library(
    name = "mylib",
    srcs = ["mylib.so"],
    hdrs = ["mylib.h"],
)

Bằng cách này, các mục tiêu C++ khác trong không gian làm việc của bạn có thể phụ thuộc vào quy tắc này.