首页 > 解决方案 > 没有 srcs 的 Bazel cc_library 不能自行编译

问题描述

我有一个只有标头的 cc_library。每当我尝试自己编译这样的库时,它实际上不会编译任何东西。我故意放了一些错误来试图在编译时得到这样的错误,但 bazel 实际上并没有编译任何东西。这是一个小例子。

// test.h

This should not compile fdsafdsafdsa
int foo() { return 1; }
# BUILD

cc_library(
  name = 'test',
  hdrs = ['test.h']
)
// bazel build :test
INFO: Analyzed target //:test (2 packages loaded, 3 targets configured).
INFO: Found 1 target...
Target //:test up-to-date (nothing to build)
INFO: Elapsed time: 0.083s, Critical Path: 0.00s
INFO: 0 processes.
INFO: Build completed successfully, 1 total action

这种行为是有意的吗?

我也进行了相同的实验,但拆分了 .h 和 .cc 文件,在这种情况下,我在编译时遇到了错误。

标签: c++bazel

解决方案


cc_library(其他规则以及包括pkg_tar例如)不必有任何来源。这也是有效的:

cc_library(
    name = "empty",
    srcs = [],
)

它实际上也非常有用。您可能具有可配置的属性,例如deps(或srcs),其中实际内容仅适用于某些条件:

cc_binary(
    name = "mybinary",
    srcs = ["main.c"],
    deps = select({
        ":platform1": [":some_plat1_only_lib"],
        ":platform2": [":empty"],  # as defined in the above snippet
    }),
)

或者(因为上面你可以很好地用于[]:platform2 deps如果你有一个更大的树并且你希望开发人员只依赖于//somelib:somelib,你可以通过一个使用这个空库alias来给他们一个标签,而不必担心所有的平台具体细节以及如何处理提供某些功能的地方:

# somelib/BUILD:
alias(
    name = "somelib",
    actual = select({
        ":platform1": [":some_plat1_only_lib"],
        ":platform2": [":empty"],  # as defined in the above snippet
    }),
    visibility = ["//visibility:public"],  # set appropriately
)

并且mybinary或任何其他目标现在可以说:

cc_binary(
    name = "mybinary",
    srcs = ["main.c"],
    deps = ["//somelib"],
)

当然,正如此处的另一个答案所述,只有标头库。

同样在您在问题中使用的示例中。(bazel或不)你通常不会(也不会很有用)自己编译头文件。您只会使用它的内容,然后才会在您尝试构建标头所在的源时看到编译器失败#include。那是为了bazel build失败,另一个目标将不得不依赖于testand #include "test.h"


推荐阅读