如何在 Bazel 中包含上层参考?

use*_*618 0 bazel

我是 Bazel 的新手(版本 0.28.1)。\n如何在另一个目录中包含头文件?下面的目录结构代表了我的问题。

\n\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 WORKSPACE\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Makefile\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 hellomake.c\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 hellofunc.c\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 BUILD\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 include\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 hellomake.h\n
Run Code Online (Sandbox Code Playgroud)\n\n

使用 src 中的 Makefile 可以很好地构建树。但是,使用 Make 我可以使用“-I ../include”引用包含文件。当我尝试使用 Bazel 构建同一棵树时,我无法成功包含头文件 hellomake.h。显然,上层引用“..”不起作用。

\n\n

我的构建文件:

\n\n
cc_library (\n    name = "hellomake",\n    srcs = ["hellomake.c"],\n    hdrs = ["//include/hellomake.h"],\n    copts = ["-I include"],\n)\n\ncc_library (\n    name = "hellofunc",\n    srcs = ["hellofunc.c"],\n    hdrs = ["//include/hellomake.h"],\n    copts = ["-I include"],\n)\n\ncc_binary(\n    name = "hello",\n    deps = [ ":hellomake", ":hellofunc", ],\n)\n
Run Code Online (Sandbox Code Playgroud)\n\n

从\'.\'我的命令是:

\n\n
bazel build //src/hello\n
Run Code Online (Sandbox Code Playgroud)\n

Ond*_* K. 6

直接的答案是,您不能跨越包边界。包是工作区目录树中具有其BUILD文件的每个节点,因此最小的更改是使包含源和标题的树成为一个包(移动BUILD一个目录)并将其改为如下所示:

\n\n
cc_library (\n    name = "hellomake",\n    srcs = ["src/hellomake.c"],\n    hdrs = ["include/hellomake.h"],\n    copts = ["-I include"],\n)\n\ncc_library (\n    name = "hellofunc",\n    srcs = ["src/hellofunc.c"],\n    hdrs = ["include/hellomake.h"],\n    copts = ["-I include"],\n)\n\ncc_binary(\n    name = "hello",\n    deps = [ ":hellomake", ":hellofunc", ],\n)\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后你可以构建:

\n\n
bazel build //:hello\n
Run Code Online (Sandbox Code Playgroud)\n\n

但我怀疑这里还有更多东西需要解开。基于规则deps的链接顺序 ( ) cc_binary,我怀疑hellomake.c实际上并不是一个库,而是您的二进制文件的源及其自己的源,main()因此:

\n\n
    \n
  • 可以直接这样声明
  • \n
  • hellomake.h实际上是 的接口并且hellofunc.c应该相应地命名
  • \n
\n\n

基于该假设,该BUILD文件现在如下所示:

\n\n
cc_library (\n    name = "hellofunc",\n    srcs = ["src/hellofunc.c"],\n    hdrs = ["include/hellofunc.h"],\n    includes = ["include"],\n)\n\ncc_binary (\n    name = "hello",\n    srcs = ["src/hellomake.c"],\n    deps = [":hellofunc"],\n)\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,如果您实际上想将源文件和标头用作单独的包,您可以这样做,但是您必须通过将其放入以下内容来将头文件声明为cc_libraryin//include./include/BUILD

\n\n
cc_library (\n    name = "hellofunc_hdr",\n    hdrs = ["hellofunc.h"],\n    includes = ["."],\n    visibility = ["//src:__pkg__"],\n)\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后在//src( ./src/BUILD) 中你可以说:

\n\n
cc_library (\n    name = "hellofunc",\n    srcs = ["hellofunc.c"],\n    deps = ["//include:hellofunc_hdr"],\n)\n\ncc_binary (\n    name = "hello",\n    srcs = ["hellomake.c"],\n    deps = [":hellofunc"],\n)\n
Run Code Online (Sandbox Code Playgroud)\n\n

这样你就可以运行了bazel build //src:hello

\n\n

诚然,这看起来有点奇怪,而且这样的包装似乎没有传达太多有意义的结构,所以也许我们最终可能会拥有一个 hellofunc (库)作为一个 ( func) 包,而 hellomake 作为我们的二进制文件的源作为另一个 ( hello) 。这棵树看起来像这样:

\n\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 WORKSPACE\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 func\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 BUILD\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 hellofunc.c\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 hellofunc.h\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 hello\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 BUILD\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 hellomake.c\n
Run Code Online (Sandbox Code Playgroud)\n\n

BUILD中的文件可能./func/是:

\n\n
cc_library (\n    name = "func",\n    srcs = ["hellofunc.c"],\n    hdrs = ["hellofunc.h"],\n    includes = ["."],\n    visibility = ["//hello:__pkg__"],\n)\n
Run Code Online (Sandbox Code Playgroud)\n\n

随着./hello/

\n\n
cc_binary (\n    name = "hello",\n    srcs = ["hellomake.c"],\n    deps = ["//func"],\n)\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后我们就可以运行build bazel //hello

\n