如何在Bazel中包含高级参考?

如何在Bazel中包含高级参考?,bazel,Bazel,我是Bazel(版本0.28.1)的新手。 如何在另一个目录中包含头文件?下面的目录结构代表了我的问题 . ├── WORKSPACE ├── src │   ├── Makefile │   ├── hellomake.c │   ├── hellofunc.c │   └── BUILD └── include └── hellomake.h 该树使用src中的Makefile构建良好。但是,使用Make,我可以引用带有“-I../include”的include文件。当我试图用B

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

.
├── WORKSPACE
├── src
│   ├── Makefile
│   ├── hellomake.c
│   ├── hellofunc.c
│   └── BUILD
└── include
    └── hellomake.h
该树使用src中的Makefile构建良好。但是,使用Make,我可以引用带有“-I../include”的include文件。当我试图用Bazel构建同一棵树时,我无法成功地包含头文件hellomake.h。显然,上层引用“…”不起作用

我的生成文件:

cc_library (
    name = "hellomake",
    srcs = ["hellomake.c"],
    hdrs = ["//include/hellomake.h"],
    copts = ["-I include"],
)

cc_library (
    name = "hellofunc",
    srcs = ["hellofunc.c"],
    hdrs = ["//include/hellomake.h"],
    copts = ["-I include"],
)

cc_binary(
    name = "hello",
    deps = [ ":hellomake", ":hellofunc", ],
)
从“”,我的命令是:

bazel build //src/hello

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

cc_library (
    name = "hellomake",
    srcs = ["src/hellomake.c"],
    hdrs = ["include/hellomake.h"],
    copts = ["-I include"],
)

cc_library (
    name = "hellofunc",
    srcs = ["src/hellofunc.c"],
    hdrs = ["include/hellomake.h"],
    copts = ["-I include"],
)

cc_binary(
    name = "hello",
    deps = [ ":hellomake", ":hellofunc", ],
)
然后,您可以构建:

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

  • 它可以直接宣布为这样
  • hellomake.h
    实际上是
    hellofunc.c
    的接口,应该相应地命名
基于该假设,
构建
文件现在如下所示:

cc_library (
    name = "hellofunc",
    srcs = ["src/hellofunc.c"],
    hdrs = ["include/hellofunc.h"],
    includes = ["include"],
)

cc_binary (
    name = "hello",
    srcs = ["src/hellomake.c"],
    deps = [":hellofunc"],
)
.
├── WORKSPACE
├── func
│   ├── BUILD
│   ├── hellofunc.c
│   └── hellofunc.h
└── hello
    ├── BUILD
    └── hellomake.c
现在,如果您确实想将源文件和头文件作为单独的包使用,您可以这样做,但是您必须在
//include
中声明头文件作为
cc\u库
,方法是将其放入
/include/BUILD

cc_library (
    name = "hellofunc_hdr",
    hdrs = ["hellofunc.h"],
    includes = ["."],
    visibility = ["//src:__pkg__"],
)
然后在
//src
/src/BUILD
)中,您可以说:

cc_library (
    name = "hellofunc",
    srcs = ["hellofunc.c"],
    deps = ["//include:hellofunc_hdr"],
)

cc_binary (
    name = "hello",
    srcs = ["hellomake.c"],
    deps = [":hellofunc"],
)
有了它,您可以运行
bazel-build//src:hello

诚然,这看起来有点奇怪,这样的打包似乎没有传达多少有意义的结构,因此,也许我们最终可以将hellofunc(library)作为一个(
func
)包,将hellomake作为二进制文件的源(
hello
)。这棵树看起来像这样:

cc_library (
    name = "hellofunc",
    srcs = ["src/hellofunc.c"],
    hdrs = ["include/hellofunc.h"],
    includes = ["include"],
)

cc_binary (
    name = "hello",
    srcs = ["src/hellomake.c"],
    deps = [":hellofunc"],
)
.
├── WORKSPACE
├── func
│   ├── BUILD
│   ├── hellofunc.c
│   └── hellofunc.h
└── hello
    ├── BUILD
    └── hellomake.c
/func/
中的
构建
文件可以是:

cc_library (
    name = "func",
    srcs = ["hellofunc.c"],
    hdrs = ["hellofunc.h"],
    includes = ["."],
    visibility = ["//hello:__pkg__"],
)
/hello/
中使用:

cc_binary (
    name = "hello",
    srcs = ["hellomake.c"],
    deps = ["//func"],
)

然后我们可以运行
buildbazel//hello

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

cc_library (
    name = "hellomake",
    srcs = ["src/hellomake.c"],
    hdrs = ["include/hellomake.h"],
    copts = ["-I include"],
)

cc_library (
    name = "hellofunc",
    srcs = ["src/hellofunc.c"],
    hdrs = ["include/hellomake.h"],
    copts = ["-I include"],
)

cc_binary(
    name = "hello",
    deps = [ ":hellomake", ":hellofunc", ],
)
然后,您可以构建:

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

  • 它可以直接宣布为这样
  • hellomake.h
    实际上是
    hellofunc.c
    的接口,应该相应地命名
基于该假设,
构建
文件现在如下所示:

cc_library (
    name = "hellofunc",
    srcs = ["src/hellofunc.c"],
    hdrs = ["include/hellofunc.h"],
    includes = ["include"],
)

cc_binary (
    name = "hello",
    srcs = ["src/hellomake.c"],
    deps = [":hellofunc"],
)
.
├── WORKSPACE
├── func
│   ├── BUILD
│   ├── hellofunc.c
│   └── hellofunc.h
└── hello
    ├── BUILD
    └── hellomake.c
现在,如果您确实想将源文件和头文件作为单独的包使用,您可以这样做,但是您必须在
//include
中声明头文件作为
cc\u库
,方法是将其放入
/include/BUILD

cc_library (
    name = "hellofunc_hdr",
    hdrs = ["hellofunc.h"],
    includes = ["."],
    visibility = ["//src:__pkg__"],
)
然后在
//src
/src/BUILD
)中,您可以说:

cc_library (
    name = "hellofunc",
    srcs = ["hellofunc.c"],
    deps = ["//include:hellofunc_hdr"],
)

cc_binary (
    name = "hello",
    srcs = ["hellomake.c"],
    deps = [":hellofunc"],
)
有了它,您可以运行
bazel-build//src:hello

诚然,这看起来有点奇怪,这样的打包似乎没有传达多少有意义的结构,因此,也许我们最终可以将hellofunc(library)作为一个(
func
)包,将hellomake作为二进制文件的源(
hello
)。这棵树看起来像这样:

cc_library (
    name = "hellofunc",
    srcs = ["src/hellofunc.c"],
    hdrs = ["include/hellofunc.h"],
    includes = ["include"],
)

cc_binary (
    name = "hello",
    srcs = ["src/hellomake.c"],
    deps = [":hellofunc"],
)
.
├── WORKSPACE
├── func
│   ├── BUILD
│   ├── hellofunc.c
│   └── hellofunc.h
└── hello
    ├── BUILD
    └── hellomake.c
/func/
中的
构建
文件可以是:

cc_library (
    name = "func",
    srcs = ["hellofunc.c"],
    hdrs = ["hellofunc.h"],
    includes = ["."],
    visibility = ["//hello:__pkg__"],
)
/hello/
中使用:

cc_binary (
    name = "hello",
    srcs = ["hellomake.c"],
    deps = ["//func"],
)
然后我们可以运行
buildbazel//hello