Bazel入门2:C++编译常见用例
来源:互联网 发布:syslog apache 编辑:程序博客网 时间:2024/05/17 20:14
1. 在一个target中包含多个文件
可以利用glob在单个target中包含多个文件,例如:
cc_library( name = "build-all-the-files", srcs = glob(["*.cc"]) hdrs = glob(["*.h"]),)
在这个target中,Bazel会编译BUILD文件所在目录下的所有.cc和.h文件(不包括子目录)。
2.includes可以进行传递
如果一个文件包括头文件,那么这个文件的规则也受到头文件所包含的库的影响咯?其实,我们只需要指定直接的依赖项为依赖项即可。比如说,假如sandwich.h
包含bread.h
,bread.h
又包含floor.h
,那么sandwich.h
是不用显式包含flour.h
的,所以BUILD文件如下写:
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"],)
3. 添加include路径
有时不能(或不愿)让依赖文件的路径包含其相对于工作区根目录的路径。因为现有的库可能已经拥有了与工作区路径不匹配的目录。例如,假设有以下目录结构:
└── my-project ├── third_party │ └── some_lib │ ├── BUILD │ ├── include │ │ └── some_lib.h │ └── some_lib.cc └── WORKSPACE
Bazel 希望some_lib.h
被include的时候是以third_party/some_lib/include/some_lib.h
这一路径来include的,但是some_lib.cc
包含它的时候用的路径却是include/some_lib.h
。为了使包含路径有效, third_party/some_lib/BUILD
需要指定some_lib
是一个包含目录:
cc_library( name = "some_lib", srcs = ["some_lib.cc"], hdrs = ["some_lib.h"], copts = ["-Ithird_party/some_lib"],)
这一点对于加入外部依赖项非常有用。
4. 包含外部库
假设你正在使用Google Test.你可以在WORKSPACE文件中使用一种new_
的repo function来下载Google Test并且把它用于你的repo:
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的BUILD文件。Google Test有几个特殊要求使它的cc_library
规则更加复杂:
googletest-release-1.7.0/src/gtest-all.cc
包含了googletest-release-1.7.0/src/
中的所有其他文件,所以我们需要在编译时去掉它,否则会由于duplicate symbols而出现link errors。- 所使用的头文件都是相对于
googletest-release-1.7.0/include/
目录的 ("gtest/gtest.h"
),所以我们必须把这个文件加到include路径中。 - 它还需要link
pthread
, 所以我们以linkopt
的方式加。
那么根据以上规则,BUILD文件可以写成这样:
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"],)
这看起来有点乱:一切都加了个前缀googletest-1.7.0
作为archive文件结构的副产品。我们可以通过添加strip_prefix
属性使new_http_archive
带上这个前缀:
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
。
5. 编写并运行C++测试程序
例如,我们可以创建一个测试程序./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
添加"//test:__pkg__"
可见属性。
现在可以用Bazel test
运行测试了。
bazel test test:hello-test
这会得到如下的output:
INFO: Found 1 test target...Target //test:hello-test up-to-date: bazel-bin/test/hello-testINFO: Elapsed time: 4.497s, Critical Path: 2.53s//test:hello-test PASSED in 0.3sExecuted 1 out of 1 tests: 1 test passes.
6.在预编译上添加依赖
如果你想使用一个库,但是你只有编译好的版本,包装在一个cc_library
规则里,例如你只有头文件和一个.so文件
cc_library( name = "mylib", srcs = ["mylib.so"], hdrs = ["mylib.h"],)
然后在工作区中其他的C ++程序,就可以使用这条规则了。
Reference
- Introduction to Bazel: Common C++ Build Use Cases
- Bazel入门2:C++编译常见用例
- Bazel入门:编译C++项目
- Bazel入门
- Bazel的入门
- bazel
- bazel
- c编译常见错误
- Redhat环境下编译安装Google Bazel
- Redhat环境下编译安装bazel
- 在mips平台编译bazel源码
- 常见的c编译错误
- C/C++编译常见错误
- c语言常见编译错误
- C语言编译常见错误
- C语言-常见编译错误
- linux下使用bazel编译tensorflow安卓源码
- C语言入门编译工具
- 常见c语言编译错误解析
- HTTP状态码
- 设计模式-享元模式
- python调用zxing项目进行二维码识别
- CCF 201409-3 字符串匹配 C语言解法
- SolrCloud集群的配置和使用
- Bazel入门2:C++编译常见用例
- iOS11适配 以及会遇到的坑
- bootstrap----导航栏 图片布局
- 自顶向下,逐步求精
- Oracle数据库冷备份、热备份
- 解决问题:Ubuntu启动卡在grub,或卡在initramfs及其他启动问题
- Microsoft Word 2010
- 游戏服务邮箱229401871@qq.com
- LeetCode Reverse Integer