转载:https://www.jianshu.com/p/4e778df3c13b
bazel的所有代码都在当前工程,每个工程都是一个 WORKSPACE 。
每个WORKSPACE下有多个BUILD文件。
BUILD内是多个targets,这些targets都是以starlark语言声明。
规则
bazel [<startup options>] <command> [<args>]
或
bazel [<startup options>] <command> [<args>] -- [<target patterns>]
action graph: bazel依赖这个图来追踪文件变化,以及是否需要重新编译,并且还可以为用户提供代码之间的依赖关系图。
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
hdrs = ["hello-greet.h"],
)
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
":hello-greet",
],
)
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
hdrs = ["hello-greet.h"],
)
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
":hello-greet",
"//lib:hello-time",
],
)
:hello-time 定义在 lib 目录
不同的目录BUILD在bazel中被称为 不同的package
cc_library(
name = "hello-time",
srcs = ["hello-time.cc"],
hdrs = ["hello-time.h"],
visibility = ["//main:__pkg__"],
)
可以在每个package的BUILD文件顶部声明其中的targets对其他包的默认可见性
package(
default_visibility = [
"//tensorflow_serving:internal",
],
features = ["-layering_check"],
)
对所有包可见声明如下
cc_proto_library(
name = "cc_echo_c++_proto",
deps = [
":echo_c++_proto",
],
visibility = [
"//visibility:public",
],
)
有2种
cc_library(
name = "mylib",
srcs = ["mylib.cc"],
hdrs = ["mylib.h"],
deps = [":lower-level-lib"]
)
cc_test(
name = "mylib_test",
srcs = ["mylib_test.cc"],
deps = [":mylib"]
)
#include "foo/bar/baz.h"
, 系统目录用 #include <foo/bar/baz.h>
.
和 ..
include_prefix
和 strip_include_prefix
有时候依赖第三方库的时候,这些库里的文件已有的include path如果放到当前目录,会不符合从workspace root引用文件的规则,就需要添加目录,比如下面的目录
└── my-project
├── legacy
│ └── some_lib
│ ├── BUILD
│ ├── include
│ │ └── some_lib.h
│ └── some_lib.cc
└── WORKSPACE
以上,bazel要求some_lib.h
必须以legacy/some_lib/include/some_lib.h
这个形式包含,但some_lib.cc
现在是"include/some_lib.h"
这样包含的,要使这个include path有效,需要按如下方式指定路径(待验证):
cc_library(
name = "some_lib",
srcs = ["some_lib.cc"],
hdrs = ["include/some_lib.h"],
copts = ["-Ilegacy/some_lib/include"],
)
使用glob
cc_library(
name = "build-all-the-files",
srcs = glob(["*.cc"]),
hdrs = glob(["*.h"]),
)
如果包含了其他头文件,就要把这个头文件的target包含进来。这个头文件内部的include则不用管。比如
sandwich依赖bread,bread依赖flour,但sandwich不依赖flour。
cc_library(
name = "sandwich",
srcs = ["sandwich.cc"],
hdrs = ["sandwich.h"],
deps = [":bread"],
)
cc_library(
name = "bread",
srcs = ["bread.cc"],
hdrs = ["bread.h"],
deps = [":flour"],
)
cc_library(
name = "flour",
srcs = ["flour.cc"],
hdrs = ["flour.h"],
)
cc_library(
name = "source_adapter",
hdrs = ["source_adapter.h"],
visibility = [
"//visibility:public",
],
deps = [
":loader",
":servable_data",
":source",
":storage_path",
":target",
"//tensorflow_serving/util:class_registration",
"@org_tensorflow//tensorflow/core:lib",
],
)
假设我们要使用Google Test,可以在WORKSPACE中这样指定:
new_http_archive(
name = "gtest",
url = "https://github.com/google/googletest/archive/release-1.7.0.zip",
sha256 = "b58cb7547a28b2c718d1e38aee18a3659c9e3ff52440297e965f5edffe34b6d0",
build_file = "gtest.BUILD",
)
【注】如果库已经包含了一个BUILD文件,可以使用 non-new_
函数。
创建文件gtest.BUILD
,这个文件用来编译Google Test,由于google test比较特殊的需求,所以它的编译规则会更复杂,特殊性在于:
googletest-release-1.7.0/src/gtest-all.cc
#include
了googletest-release-1.7.0/src/
下的所有文件,所以需要把这个文件排除掉googletest-release-1.7.0/include/
,比如"gtest/gtest.h"
,所以需要把这个目录加到copts的-I选项中所以,最终编译规则如下:
cc_library(
name = "main",
srcs = glob(
["googletest-release-1.7.0/src/*.cc"],
exclude = ["googletest-release-1.7.0/src/gtest-all.cc"]
),
hdrs = glob([
"googletest-release-1.7.0/include/**/*.h",
"googletest-release-1.7.0/src/*.h"
]),
copts = [
"-Iexternal/gtest/googletest-release-1.7.0/include"
],
linkopts = ["-pthread"],
visibility = ["//visibility:public"],
)
这个看起来有点乱,因为里面包含了那个版本目录名,这个名字可以在new_http_archive
中使用strip_prefix
去掉:
new_http_archive(
name = "gtest",
url = "https://github.com/google/googletest/archive/release-1.7.0.zip",
sha256 = "b58cb7547a28b2c718d1e38aee18a3659c9e3ff52440297e965f5edffe34b6d0",
build_file = "gtest.BUILD",
strip_prefix = "googletest-release-1.7.0",
)
去掉后的gtest.BUILD文件如下:
cc_library(
name = "main",
srcs = glob(
["src/*.cc"],
exclude = ["src/gtest-all.cc"]
),
hdrs = glob([
"include/**/*.h",
"src/*.h"
]),
copts = ["-Iexternal/gtest/include"],
linkopts = ["-pthread"],
visibility = ["//visibility:public"],
)
现在,其他的 cc_ rules
可以依赖于 @gtest//:main
。
更详细的cc rule说明参考 cc rules
创建文件 ./test/hello-test.cc
#include "gtest/gtest.h"
#include "lib/hello-greet.h"
TEST(HelloTest, GetGreet) {
EXPECT_EQ(get_greet("Bazel"), "Hello Bazel");
}
创建 ./test/BUILD
cc_test(
name = "hello-test",
srcs = ["hello-test.cc"],
copts = ["-Iexternal/gtest/include"],
deps = [
"@gtest//:main",
"//lib:hello-greet",
],
)
注意,要使hello-greet
对hello-test
可见,需要在 ./lib/BUILD
文件中添加属性visibility
,值为 //test:__pkg__
。
运行测试用例:
bazel test test:hello-test
输出:
INFO: Found 1 test target...
Target //test:hello-test up-to-date:
bazel-bin/test/hello-test
INFO: Elapsed time: 4.497s, Critical Path: 2.53s
//test:hello-test PASSED in 0.3s
Executed 1 out of 1 tests: 1 test passes.
该部分来自于 bazel C++ use case
cc_library(
name = "mylib",
srcs = ["mylib.so"],
hdrs = ["mylib.h"],
)
Working with external dependencies
需要编写BUILD文件
原文:https://www.cnblogs.com/qiandeheng/p/12419606.html