2019独角兽企业重金招聘Python工程师标准>>>

  • 原文:http://www.bazel.io/docs/cpp.html
  • 译者:chai2010

使用绝对路径

包含的路径是相对于工作区的根路径。假设有以下的目录结构:

[workspace]/WORKSPACEa/BUILDa.ha.ccb/BUILDb.hb.ccmain.cc

如果b/main.cc需要包含b.h头文件,我们需要创建以下的b/BUILD文件:

cc_library(name = "b",srcs = ["b.cc"],hdrs = ["b.h"],
)cc_binary(name = "main",srcs = ["main.cc"],deps = [":b"],
)

b/main.cc可以这样包含b.h

#include "b/b.h"

上面的头文件包含路径是相对于工作区根目录的相对路径。如果b/main.cc还要依赖a/a.h头文件的话,我们还需要添加a/BUILD文件:

cc_library(name = "a",srcs = ["a.cc"],hdrs = ["a.h"],visibility = ["//b:__pkg__"],
)

然后我们在b/BUILD添加依赖关系:

cc_binary(name = "main",srcs = ["main.cc"],deps = [":b","//a",],
)

b/main.cc代码中也包含了a/a.h头文件:

#include "a/a.h"

b/main.cc就可以正常使用a/a.hb/b.h中导出的符号了。

依赖传递

如果包含了一个头文件,那么需要将头文件对应的库添加到依赖中。不过,只需有添加直接依赖的库。假设三明治对应的sandwich.h文件包含了面包对应的bread.h文件,同时bread.h又包含了面粉对应的flour.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"],
)

上面表示了sandwich三明治库依赖bread面包库,bread又依赖flour对应的面粉库。

添加头文件包含路径

很多时候你可能并不希望基于工作区根路径的相对路径来包含每个头文件。因为很多已经存在的第三方库的头文件包含方式并不是基于工作区的根路径。假设有以下目录结构:

[workspace]/WORKSPACEthird_party/some_lib/include/some_lib.hBUILDsome_lib.cc

Bazel希望用third_party/some_lib/include/some_lib.h方式包含some_lib.h,但是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"],
)

这对于依赖的外部第三方库特别有效,因为可以避免在头文件路径中出现无关的external/[repository-name]/前缀。

包含外部库:一个例子

假设使用了 Google Test。可以在WORKSPACE文件中使用new_开头的仓库相关的函数,下载依赖的GTest代码到当前仓库中:

new_http_archive(name = "gtest",url = "https://googletest.googlecode.com/files/gtest-1.7.0.zip",sha256 = "247ca18dd83f53deb1328be17e4b1be31514cedfc1e3424f672bf11fd7e0d60d",build_file = "gtest.BUILD",
)

创建gtest.BUILD文件,对应Google Test的构建配置文件。配置文件中有几个需要特别注意的地方:

  • gtest-1.7.0/src/gtest-all.cc文件已经采用#include语法包含了gtest-1.7.0/src/目录中其它*.cc文件,因此需要将它排除在外(也可以只包含它一个文件,但是需要正确配置包含路径)。
  • 它的头文件在gtest-1.7.0/include/目录,需要将它添加到头文件包含路径列表中
  • GTest依赖pthread多线程库,通过linkopt选项指定。

最终的规则大概是这样:

cc_library(name = "main",srcs = glob(["gtest-1.7.0/src/*.cc"],exclude = ["gtest-1.7.0/src/gtest-all.cc"]),hdrs = glob(["gtest-1.7.0/include/**/*.h","gtest-1.7.0/src/*.h"]),copts = ["-Iexternal/gtest/gtest-1.7.0/include"],linkopts = ["-pthread"],visibility = ["//visibility:public"],
)

这是有点混乱:所有以gtest-1.7.0为前缀的其实都是生成的临时文件。我们可以通过new_http_archive函数中的strip_prefix属性来忽略它:

new_http_archive(name = "gtest",url = "https://googletest.googlecode.com/files/gtest-1.7.0.zip",sha256 = "247ca18dd83f53deb1328be17e4b1be31514cedfc1e3424f672bf11fd7e0d60d",build_file = "gtest.BUILD",strip_prefix = "gtest-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_相关的规则可以通过//external:gtest/main引用GTest了。

例如:我们可以创建以下测试:

#include "gtest/gtest.h"TEST(FactorialTest, Negative) {EXPECT_EQ(1, 1);
}

创建对应的BUILD文件:

cc_test(name = "my_test",srcs = ["my_test.cc"],copts = ["-Iexternal/gtest/include"],deps = ["@gtest//:main"],
)

使用bazel test命令运行测试。

依赖预编译的库

如果要依赖一个已经编译好的库(可能只有头文件和对应的*.so库文件),可以使用cc_library规则包装一个库对象:

cc_library(name = "mylib",srcs = ["mylib.so"],hdrs = ["mylib.h"],
)

其它的目标就可以依赖这个包装的库对象了。

转载于:https://my.oschina.net/chai2010/blog/701807

Bazel C++ 基础[翻译]相关推荐

  1. iOS 应用开发基础翻译 改为 笔记和总结

    实在是翻译能力不高,翻译出来的中国话怎么读都别扭,所以此系列改为阅读笔记和总结,FYI. 转载于:https://www.cnblogs.com/csusheep/p/4459623.html

  2. 懒人动手,用python做一个基础翻译重命名器(破解百度翻译反爬手段)

    想法: 在做开发的时候,经常需要命名各种变量,方法/函数,类,包,库等. 走一遍流程就是:想好要起的名字,比如"非常帅气": 然后上翻译网站,比如百度翻译,有道翻译: 将中文输入并 ...

  3. unity 接百度基础翻译

    1.上百度翻译开放平台注册账号 2.unity接入json解析的相关dll文件 using System.Collections; using System.Collections.Generic; ...

  4. Paper:2017年的Google机器翻译团队《Transformer:Attention Is All You Need》翻译并解读

    Paper:2017年的Google机器翻译团队<Transformer:Attention Is All You Need>翻译并解读 目录 论文评价 1.Motivation: 2.创 ...

  5. SQL Server内存架构基础

    SQL Server内存架构基础 翻译自: https://mssqlwiki.com/sqlwiki/sql-performance/basics-of-sql-server-memory-arch ...

  6. HTML免费在线文档批量翻译工具

    免费在线文档翻译不同于一般的段落文章复制粘贴在线翻译,免费在线文档翻译支持我们将我们的不同格式的整篇文档进行翻译,还可以将多篇文档放入我们的一个文件夹中,对这个文件夹进行批量翻译,适用于需要大量进行批 ...

  7. 编写程序实现通过有道或百度翻译url对用户输入数据进行翻译_8亿用户AI有道:超强神经网络翻译技术大解密...

    [新智元导读]数据的作用在人工智能发展道路上愈发被重视.7月27日,在广州举行的GMIC大会上,网易有道技术总监林会杰表示目前AI+教育还在初级阶段,对于这一行业而言,得数据者得先机.这家拥有国内最大 ...

  8. 编写程序实现通过有道或百度翻译url对用户输入数据进行翻译_8亿用户AI有道,超强神经网络翻译技术大解密...

    [新智元导读]数据的作用在人工智能发展道路上愈发被重视.7月27日,在广州举行的GMIC大会上,网易有道技术总监林会杰表示目前AI+教育还在初级阶段,对于这一行业而言,得数据者得先机.这家拥有国内最大 ...

  9. 《Attention Is All Y ou Need》翻译 Ashish Vaswani Noam Shazeer Niki Parmar Jakob etc.

    目录 摘要 一.介绍 二.背景 三.模型架构 3.1编码器和解码器堆栈 3.2注意力 3.2.1按比例缩小的点积的注意力 3.2.2多端注意力 3.2.3注意力在模型中的应用 3.3Position- ...

最新文章

  1. 5行代码就能入门爬虫?
  2. input缓存中选值事件触发
  3. 【博客话题】技术人生之三界修炼
  4. mysql压缩配置_MySQL压缩版安装配置
  5. Could NOT find SDL (missing: SDL_LIBRARY SDL_INCLUDE_DIR)
  6. HDU1257 最少拦截系统 贪心或动态规划
  7. [MyBatisPlus]条件构造器wapper
  8. 信息学奥赛一本通 2032:【例4.18】分解质因数
  9. 热门wordpress主题Essentials汉化绿色版[更至v2.0.0]
  10. 推荐!小议如何跳出魔改网络结构的火坑(完整版)
  11. 从浏览器启动客户端程序的方法
  12. 官方 Material Design App
  13. Android Toolbar
  14. GetRows的用法详解
  15. C#控制语音卡实现呼叫、录音以及来电弹屏
  16. linux下mysql8.0初始密码_Linux下MySQL8.0修改初始密码
  17. 美国航空发动机发展经验,给中国的启示!
  18. m3u8.sqlite转mp4(txkt,文末附程序下载地址)
  19. 文章标题 SPOJ - DRUIDEOI : Fata7y Ya Warda!(单调栈)
  20. Dell戴尔Inspiron 5498原装出厂系统恢复原厂系统1903

热门文章

  1. outlook qr码在哪里_高能手办团兑换码有哪些 高能手办团哪里兑换
  2. Window.location.href命令在JS中跳转无效或自动忽略
  3. 20191013:快速排序1.1
  4. 20190816:(leetcode习题)有效的数独
  5. c语言可作为程序分支的表达式,[计算机软件及应用]C语言程序设计4--李2012.ppt
  6. php开发当中遇到的各种问题,PHP项目开发中遇到过的问题
  7. python线程数组_Python多线程
  8. 20年未解的MIT密码难题,被自学成才的程序员破解了,比预计早15年
  9. 寻找优秀的AI公司与受人尊敬的资本助推者 | 量子位年度评选进行时
  10. 圣诞节吃饺子时,怎么给女票解释啥是AI?