forked from ApolloAuto/apollo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Docs: added "Introduction to Release Build" in Chinese
- Loading branch information
Showing
3 changed files
with
200 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
198 changes: 198 additions & 0 deletions
198
docs/technical_tutorial/intro_to_apollo_release_build_cn.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
# Apollo Release Build 简介 | ||
|
||
## 背景 | ||
|
||
基于 CyberRT 的 Apollo 在相当长的时间内一直没有二进制发布版本。用户需要先在 | ||
Apollo 开发容器内自行完成对整个项目的编译构建才能运行 Apollo 中的模块和工具。这 | ||
种部署上的不足,在若干情形下对用户相当不便。SVL 模拟器的开发者发现,将 Apollo | ||
中 Docker 镜像、Docker 卷及 Bazel 缓存和构建查出加起来,足有 40 多 GB! | ||
|
||
## Release Build 的实现原理 | ||
|
||
这种部署上的不足的根本原因,在于 Bazel 缺少其他构建系统通常具备的开箱即用的「安 | ||
装」支持,如`make install`. | ||
|
||
为解决这一问题,我们借鉴了[Drake](https://github.com/RobotLocomotion/drake) 项目 | ||
中的「安装」实现,,利用 Starlark 语言,实现了 适用于 Apollo 的 Bazel「安装」扩 | ||
展,支持 Apollo 中二进制程序、共享库、资源文件(配置、数据、DAG 文件等)以及文档 | ||
的安装。 | ||
|
||
单独完备的二进制程序的安装是简单的。然而,CyberRT 框架的核心概念即为将每个模块( | ||
如感知、预测、规划)作为组件,以共享库的形式(`libX_component.so`)动态加载。在 | ||
目前的 Bazel 构建下,`mainboard`二进制程序和`libX_component.so`链接了成千上百各 | ||
其他共享库对象。如,对规划模块运行如下`ldd`命令: | ||
|
||
```bash | ||
ldd bazel-bin/modules/planning/libplanning_component.so | ||
``` | ||
|
||
会输出如下消息: | ||
|
||
```text | ||
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](../../tools/install/install.bzl)。 | ||
|
||
## 如何执行 Release Build 构建 | ||
|
||
可运行如下命令以生成二进制发布构建产物: | ||
|
||
```bash | ||
./apollo.sh release -c | ||
``` | ||
|
||
其中,`-c`为可选参数,用于清理先前构建的残留。产物位于`/apollo/output`目录。 | ||
|
||
上述命令略等价于如下 Bazel 命令: | ||
|
||
```bash | ||
bazel run --config=opt --config=gpu //:install \ | ||
-- --pre_clean /apollo/output | ||
``` | ||
|
||
可输入`./apollo.sh release -h` 查看`apollo.sh release`子命令的更多用法。 | ||
|
||
## 通过二进制发布构建产物运行 Apollo | ||
|
||
在二进制发布产物根目录下,运行如下命令以启动 Apollo Runtime Docker 镜像: | ||
|
||
```bash | ||
bash docker/scripts/runtime_start.sh | ||
``` | ||
|
||
国内用户可使用`-g cn`选项来加速 Docker 镜像的拉取。 | ||
|
||
```bash | ||
bash docker/scripts/runtime_start.sh -g cn | ||
``` | ||
|
||
运行如下命令以进入 Apollo Runtime Docker 环境: | ||
|
||
```bash | ||
bash docker/scripts/runtime_into.sh | ||
``` | ||
|
||
启动 Dreaview: | ||
|
||
```bash | ||
./scripts/bootstrap.sh | ||
``` | ||
|
||
## 如何将`install`规则应用到任一自定义模块 | ||
|
||
欲实现自定义模块的*安装*,可参考 Apollo 代码中其他模块的示例,还是以规划模块为例 | ||
: | ||
|
||
这是最上层的[BUILD](../../BUILD) 文件的一部分: | ||
|
||
```python | ||
install( | ||
name = "install", | ||
deps = [ | ||
"//cyber:install", | ||
# ... | ||
"//modules/planning:install", | ||
# ... | ||
], | ||
) | ||
``` | ||
|
||
这是规划模块自身的 BUILD 文件 | ||
[modules/planning/BUILD](../../modules/planning/BUILD): | ||
|
||
```python | ||
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`规则的参数列表 | ||
|
||
`install`规则定义在 | ||
[tools/install/install.bzl](../../tools/install/install.bzl): | ||
|
||
```python | ||
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 支持尚待完善。 |