首页 > 解决方案 > 在 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",
    ]
)

上面我也试过用hdrsandtextual_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。

标签: c++cmakebuildgoogletestbazel

解决方案


# 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 中,您应该创建面向功能的包,而不是按层。srcincludetest
  • 在您的代码中,library_test目标不会看到来自library目标的标头,您必须通过deps属性将其作为依赖项传递。Bazel 使用沙盒TL;DR:操作看不到文件,这些文件未明确定义为依赖项
  • 不要使用copts = ["-Iproject/include"]. 当一切都正确完成时,Bazel 会为您完成:在这种情况下,您必须向目标添加includes属性library。包含路径将设置在 a 中library_test,因为测试目标取决于library

推荐阅读