Skip to content

Commit

Permalink
Docs: added "Introduction to Release Build" in Chinese
Browse files Browse the repository at this point in the history
  • Loading branch information
storypku committed Mar 23, 2021
1 parent a265783 commit 4fc0510
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/technical_tutorial/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ Refer these documents as a guide to all other relevant documents for the version
- [Navigation Mode in Apollo 2.5 中文版](navigation_mode_tutorial_cn.md)
- [Apollo Best Coding Practice](apollo_best_coding_practice.md)
- [Introduction to Apollo Release Build](intro_to_apollo_release_build.md)
- [Introduction to Apollo Release Build 中文版](intro_to_apollo_release_build_cn.md)

2 changes: 1 addition & 1 deletion docs/technical_tutorial/intro_to_apollo_release_build.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ For quite some time, binary distribution was unavailable for CyberRT-based
Apollo. Users have to build the whole project themselves inside Apollo Dev
container before they can run various modules and tools. This incapability of
deployment causes trouble in certain situations. For example, people from
Lgsvl-Simulator find that the total size of all Docker images, volumes and Bazel
SVL Simulator find that the total size of all Docker images, volumes and Bazel
caches and build artifacts sums up to 40+ GB, which was rather inconvenient for
their use case.

Expand Down
198 changes: 198 additions & 0 deletions docs/technical_tutorial/intro_to_apollo_release_build_cn.md
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 支持尚待完善。

0 comments on commit 4fc0510

Please sign in to comment.