基于 CyberRT 的 Apollo 在相当长的时间内一直没有二进制发布版本。用户需要先在 Apollo 开发容器内自行完成对整个项目的编译构建才能运行 Apollo 中的模块和工具。这 种部署上的不足,在若干情形下对用户相当不便。SVL 模拟器的开发者发现,将 Apollo 中 Docker 镜像、Docker 卷及 Bazel 缓存和构建查出加起来,足有 40 多 GB!
这种部署上的不足的根本原因,在于 Bazel 缺少其他构建系统通常具备的开箱即用的「安
装」支持,如make install
.
为解决这一问题,我们借鉴了Drake 项目 中的「安装」实现,,利用 Starlark 语言,实现了 适用于 Apollo 的 Bazel「安装」扩 展,支持 Apollo 中二进制程序、共享库、资源文件(配置、数据、DAG 文件等)以及文档 的安装。
单独完备的二进制程序的安装是简单的。然而,CyberRT 框架的核心概念即为将每个模块(
如感知、预测、规划)作为组件,以共享库的形式(libX_component.so
)动态加载。在
目前的 Bazel 构建下,mainboard
二进制程序和libX_component.so
链接了成千上百各
其他共享库对象。如,对规划模块运行如下ldd
命令:
ldd bazel-bin/modules/planning/libplanning_component.so
会输出如下消息:
linux-vdso.so.1 (0x00007ffc8a77c000)
libmodules_Splanning_Slibplanning_Ucomponent_Ulib.so => /apollo/bazel-bin/modules/planning/../../_solib_local/libmodules_Splanning_Slibplanning_Ucomponent_Ulib.so (0x00007fe8a7f9f000)
libmodules_Splanning_Slibnavi_Uplanning.so => /apollo/bazel-bin/modules/planning/../../_solib_local/libmodules_Splanning_Slibnavi_Uplanning.so (0x00007fe8a7d81000)
libmodules_Splanning_Slibon_Ulane_Uplanning.so => /apollo/bazel-bin/modules/planning/../../_solib_local/libmodules_Splanning_Slibon_Ulane_Uplanning.so (0x00007fe8a7b53000)
libmodules_Splanning_Slibplanning_Ubase.so => /apollo/bazel-bin/modules/planning/../../_solib_local/libmodules_Splanning_Slibplanning_Ubase.so (0x00007fe8a7945000)
libmodules_Splanning_Scommon_Ssmoothers_Slibsmoother.so => /apollo/bazel-bin/modules/planning/../../_solib_local/libmodules_Splanning_Scommon_Ssmoothers_Slibsmoother.so (0x00007fe8a7739000)
libmodules_Splanning_Splanner_Slibplanner_Udispatcher.so => /apollo/bazel-bin/modules/planning/../../_solib_local/libmodules_Splanning_Splanner_Slibplanner_Udispatcher.so (0x00007fe8a752e000)
...
如何实现对libplanning_component.so
及其链接的所有共享库(后缀为".so")文件的「
安装」,成为实现install
规则中最难的部分。
幸好有patchelf
。利用 Bazel 中runfiles_data
的概念来确定出链接的所有共享库文件
,再利用patchelf --force-rpath --set-rpath
来修改其 RPATH 设置。
欲要更深入了解,请参考: tools/install/install.bzl。
可运行如下命令以生成二进制发布构建产物:
./apollo.sh release -c
其中,-c
为可选参数,用于清理先前构建的残留。产物位于/apollo/output
目录。
上述命令略等价于如下 Bazel 命令:
bazel run --config=opt --config=gpu //:install \
-- --pre_clean /apollo/output
可输入./apollo.sh release -h
查看apollo.sh release
子命令的更多用法。
在二进制发布产物根目录下,运行如下命令以启动 Apollo Runtime Docker 镜像:
bash docker/scripts/runtime_start.sh
国内用户可使用-g cn
选项来加速 Docker 镜像的拉取。
bash docker/scripts/runtime_start.sh -g cn
运行如下命令以进入 Apollo Runtime Docker 环境:
bash docker/scripts/runtime_into.sh
启动 Dreaview:
./scripts/bootstrap.sh
欲实现自定义模块的安装,可参考 Apollo 代码中其他模块的示例,还是以规划模块为例 :
这是最上层的BUILD 文件的一部分:
install(
name = "install",
deps = [
"//cyber:install",
# ...
"//modules/planning:install",
# ...
],
)
这是规划模块自身的 BUILD 文件 modules/planning/BUILD:
filegroup(
name = "planning_conf",
srcs = glob([
"conf/**",
]),
)
filegroup(
name = "runtime_data",
srcs = glob([
"dag/*.dag",
"launch/*.launch",
]) + [":planning_conf"],
)
install(
name = "install",
data = [
":runtime_data",
],
targets = [
":libplanning_component.so",
],
deps = [
"//cyber:install",
],
)
install
规则定义在
tools/install/install.bzl:
install = rule(
attrs = {
"deps": attr.label_list(providers = [InstallInfo]),
"data": attr.label_list(allow_files = True),
"data_dest": attr.string(default = "@PACKAGE@"),
"data_strip_prefix": attr.string_list(),
"targets": attr.label_list(),
"library_dest": attr.string(default = "@PACKAGE@"),
"library_strip_prefix": attr.string_list(),
"mangled_library_dest": attr.string(default = "lib"),
"mangled_library_strip_prefix": attr.string_list(),
"runtime_dest": attr.string(default = "bin"),
"runtime_strip_prefix": attr.string_list(),
"rename": attr.string_dict(),
"install_script_template": attr.label(
allow_files = True,
executable = True,
cfg = "target",
default = Label("//tools/install:install.py.in"),
),
},
executable = True,
implementation = _install_impl,
)
其具体参数列举如下
参数 | 含义 |
---|---|
deps | 本规则依赖的其它安装规则 |
data | 待安装的资源文件(平台无关)列表 |
data_dest | 资源文件目标安装地址 |
data_strip_prefix | 需去掉的资源文件路径前缀列表 |
targets | 待安装目标 |
runtime_dest | 可执行目标的目标安装地址,默认为 bin 目录 |
runtime_strip_prefix | 需去掉可执行目标路径的前缀 |
rename | 安装时的文件重命名 |
当前的 Release Build 实现
- 只支持 C++,不支持 Python。
- 只支持 x86_64 架构,Aarch64 支持尚待完善。