原文地址:Envoy bazel 学习 & 踩坑
近一年有开始折腾 Envoy 了,在 bazel 这块踩了一些坑,总结记录下的,主要是个人的体感,不一定准确,欢迎批评指正。
bazel 是个啥编译构建工具,跟常用的 Makefile 是类似的。
只是,bazel 更复杂,上手门槛更高,以我的个人的体验来看,主要是为了提升表达能力,可编程能力更强。
Makefile 通常是用于简单的描述,偶尔会搞个函数啥的;但是在 bazel 里,会看到大面积的自定义函数。
为啥 Envoy 需要 bazelEnvoy 是个 C++ 项目,C/C++ 这种比较老的语言,没有内置依赖包管理器这种先进特性(相比较而言,Go 语言在这块就先进了许多)。
我的理解,对于 Envoy 来说,bazel 一个主要的作用就是,补齐了依赖包管理。如果仅仅是编译,Makefile 之类的简单工具,应该也够用了。
几个概念有几个常用的基本概念,先了解一下的
WORKSPACE在项目的根目录,会有一个 WORKSPACE 文件,用于描述整个项目的,最主要是描述了依赖库,比较类似于 Go 语言中的 go.mod,go.sum。
比如 Envoy 的 WORKSPACE 文件中,有这样的描述:
load("//bazel:repositories.bzl", "envoy_dependencies")envoy_dependencies()其中,具体依赖库的详细信息,在 bazel/repository_locations.bzl 文件里。比如下面这个示例:
boringssl = dict(project_name = "BoringSSL",project_url = "https://github.com/google/boringssl",version = "098695591f3a2665fccef83a3732ecfc99acdcdd",sha256 = "e141448cf6f686b6e9695f6b6459293fd602c8d51efe118a83106752cf7e1280",strip_prefix = "boringssl-{version}",urls = ["https://github.com/google/boringssl/archive/{version}.tar.gz"],),描述的是依赖库 boringssl,是不是很像 go.mod,go.sum。
另外,在这里还可以频繁看到 @envoy @envoy_api 这种,这里也表示的一个依赖库的作用域。
BUILDBUILD 文件会有很多个,用于描述一个目标的编译过程,类似于 Makefile 中描述一个目标的构建过程。
比如,这样子的:
envoy_cc_library(name = "lua_filter_lib",srcs = ["lua_filter.cc"],hdrs = ["lua_filter.h"],deps = [":wrappers_lib","//envoy/http:codes_interface","@envoy_api//envoy/extensions/filters/http/lua/v3:pkg_cc_proto",],).bazelrc这也是在项目根目录下的,用于描述 bazel 的默认配置。
比如,这个:
build:linux --copt=-Wno-deprecated-declarations可以指定一些编译参数之类的。
执行有了上面这些描述信息之后,最终要执行编译构建的命令就简单许多了
比如:
bazel build envoy这里的构建目标 envoy,来自项目根目录下的 BUILD 文件。
也可以是这样子的:
bazel build //source/exe:envoy此时的构建目标 //source/exe:envoy,来自项目根目录下的 source/exe/BUILD 文件了。
踩过的坑除了上面这些一手体感,还有一些坑,也记录下的
变更编译器版本有一次,想换个高版本的 gcc,但是修改了 PATH 后重新构建,始终不生效。
原来是,bazel 是增量编译的,所以会使用上一次编译时使用编译器,以保证整个项目是使用的同一个编译器。
所以,如果想更换编译器,需要清空下缓存:
bazel clean --expungesplit DWARF较新版的 Envoy,启用了 -gsplit-dwarf 这个特性,也就是将调试符号放到独立的 .dwo 文件里了,以减少生成的二进制文件大小。
不过呢,这个特性还比较新,可能会有一些坑,至少在我的环境下(gdb 11,这个版本也不低了),就有 .dwo 读取错误。比如这样子的:
DW_FORM_strp pointing outside of .debug_str section所以,干脆关掉这个特性,就一切正常了(主要是 bt full 这类查看局部变量的功能)。
具体操作是,注释掉 .bazelrc 中的这一行:
# build:linux --features=per_object_debug_info最后记录下,我这边可以完整工作的环境:
g++ 11gdb 11在这个环境下,gdb 是可以完整工作的,局部变量都可以看。
之前在一个比较老的版本上,工作是不太顺利的。
如果觉得有意思,欢迎关注我的公众号 「豆浆大叔」~