c++ - 在 C++ 中只有头文件(模板类/函数)的情况下如何使用 Bazel?
问题描述
我有以下问题:假设我的项目结构是:
├── project
│ ├── include
| | ├── BUILD
| | └── library.hpp
│ ├── src
| | ├── BUILD
| | └── main.cpp
| ├── test
| | ├── BUILD
| | └── library_test.cpp
└── WORKSPACE
library.hpp
是一个包含模板类实现的文件,它包含在main.cpp
和中library_test.cpp
。
如何准备BUILD
文件,这样我在编译时就不会出现编译错误,library_test.cpp
并且main.cpp
说:
src/main.cpp:2:10: fatal error: shared_ptr.hpp: No such file or directory
2 | #include "library.hpp"
| ^~~~~~~~~~~~~~~~
compilation terminated.
我尝试的是:
include/BUILD
load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library(
name = "library",
srcs = ["library.hpp"],
includes = ["include"],
visibility = [
"//visibility:public",
]
)
上面我也试过用hdrs
andtextual_hdrs
而不是srcs
.
test/BUILD
:
load("@rules_cc//cc:defs.bzl", "cc_test")
cc_test(
name = "library_test",
srcs = ["library_test.cpp"],
deps = [
"@gtest//:gtest",
"@gtest//:gtest_main",
],
includes = ["include"],
copts = ["-Iproject/include"],
)
并且要彻底WORKSPACE
:
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
git_repository(
name = "gtest",
remote = "https://github.com/google/googletest",
branch = "v1.10.x",
)
根据我在互联网上看到的官方 bazel 教程、一些演示文稿或类似问题,我有一个问题要自己解决。它们仅在库中编写的函数定义在 cpp 文件中并且可以编译为目标文件的情况下显示使用 cc_library。
解决方案
# BUILD
cc_library(
name = "library",
hdrs= ["include/library.hpp"],
includes = ["include"],
visibility = [
"//visibility:public",
]
)
cc_test(
name = "library_test",
srcs = ["test/library_test.cpp"],
deps = [
"@gtest//:gtest_main", # gtest_main already contains gtest
":library"
],
)
cc_binary(
name = "binary",
srcs = ["src/main.cpp"],
deps = [
":library"
],
)
注意:
- 使用
hdrs
, 因为srcs
依赖目标不可见。 - //目录不要使用单独
BUILD
的文件。在 Bazel 中,您应该创建面向功能的包,而不是按层。src
include
test
- 在您的代码中,
library_test
目标不会看到来自library
目标的标头,您必须通过deps
属性将其作为依赖项传递。Bazel 使用沙盒TL;DR:操作看不到文件,这些文件未明确定义为依赖项 - 不要使用
copts = ["-Iproject/include"]
. 当一切都正确完成时,Bazel 会为您完成:在这种情况下,您必须向目标添加includes
属性library
。包含路径将设置在 a 中library_test
,因为测试目标取决于library