3. 开发环境搭建
Cyber RT 是 Apollo 自动驾驶平台中的高性能运行时框架,其数据通道(Channel)与组件(Component)机制都建立在统一的构建与运行环境之上。若环境搭建不完整,后续的通道通信、组件加载、DAG 调度都会出现难以定位的编译或运行错误。本节从源码获取、依赖安装、Bazel 构建、编译运行到最小可运行示例,完整走通一次环境搭建流程,为后续章节的通道与组件开发打下可复现的基础。
一、核心原理:Cyber RT 的构建与运行依赖链
Cyber RT 采用 Bazel 作为主构建系统,源码以 WORKSPACE 为根,通过 BUILD 文件描述目标。其运行依赖可分为四层:系统层(Ubuntu、内核、编译工具链)、第三方库层(Protobuf、gflags、glog、Fast DDS、Boost 等)、Apollo 基础层(cyber、common、proto 等模块)以及应用层(用户组件与通道定义)。理解这条依赖链,才能判断构建失败发生在哪一层。
Cyber RT 的编译产物主要包括动态库(如 libcyber.so)、可执行程序(如 cyber_node、cyber_channel)以及用户组件生成的 .so 插件。运行时通过 DAG 文件与 launch 文件加载组件,通道则通过共享内存或 Fast DDS 完成进程间通信。因此,环境搭建的目标不是“能编译”,而是“能编译且能运行一个最小通道与组件”。
二、方法流程:从源码到可运行的五步操作
以下流程以 Ubuntu 20.04 为例,假设工作目录为 ~/apollo。每一步都建议在干净终端中执行,并保留日志以便排障。
- 源码获取:克隆 Apollo 仓库并切换到稳定分支。Cyber RT 位于
cyber/目录下。 - 依赖安装:执行官方依赖脚本,安装系统包与第三方库。
- Bazel 构建:使用 Bazel 编译 cyber 核心库与工具。
- 编译运行:通过
cyber_launch启动 DAG,验证通道与组件是否正常。 - 最小示例:编写 Talker/Listener 组件,完成一次端到端通信。
# 1. 源码获取
git clone https://github.com/ApolloAuto/apollo.git
cd apollo
git checkout v9.0.0
# 2. 依赖安装
bash docker/setup_host/install_docker.sh # 如使用容器
bash apollo.sh build cyber # 或使用官方依赖脚本
# 3. Bazel 构建(在 apollo 根目录)
bazel build //cyber:cyber
bazel build //cyber/tools/cyber_monitor:cyber_monitor
# 4. 编译运行
source cyber/setup.bash
cyber_launch start cyber/examples/talker_listener.launch
# 5. 查看通道
cyber_channel list
cyber_channel echo /apollo/test
三、案例/场景:最小可运行示例 Talker/Listener
最小示例是验证环境是否真正可用的关键。它包含三个文件:消息定义 test.proto、发送组件 talker.cc、接收组件 listener.cc,以及一个 DAG 文件。Talker 周期性写入通道,Listener 订阅并打印消息。
// test.proto
syntax = "proto2";
package apollo.cyber.example;
message Test {
optional string content = 1;
}
// talker.cc 核心逻辑
bool Talker::Init() {
writer_ = node_->CreateWriter<Test>("/apollo/test");
return true;
}
bool Talker::Proc() {
auto msg = std::make_shared<Test>();
msg->set_content("hello cyber");
writer_->Write(msg);
return true;
}
// listener.cc 核心逻辑
bool Listener::Init() {
reader_ = node_->CreateReader<Test>(
"/apollo/test",
[this](const std::shared_ptr<Test>& msg) {
AINFO << "Received: " << msg->content();
});
return true;
}
DAG 文件负责把组件、通道和调度配置绑定在一起。启动后,若 cyber_channel echo /apollo/test 能持续输出 hello cyber,说明源码、依赖、构建、运行四个环节全部打通。
| 环节 | 关键命令/文件 | 成功标志 | 常见失败原因 |
|---|---|---|---|
| 源码获取 | git clone / checkout | cyber 目录存在 | 网络超时、分支错误 |
| 依赖安装 | install_deps.sh | 无缺失库报错 | apt 源、权限、版本冲突 |
| Bazel 构建 | bazel build //cyber:cyber | BUILD SUCCESSFUL | Bazel 版本、缓存污染 |
| 编译运行 | cyber_launch start | 进程常驻、无崩溃 | DAG 路径、库路径未 source |
| 最小示例 | talker_listener.launch | echo 有数据输出 | 通道名不一致、组件未注册 |
四、误区与复盘:环境搭建中最容易踩的坑
- 只编译不运行:Bazel 构建成功不代表运行成功。DAG 文件、通道名、组件注册宏(CYBER_REGISTER_COMPONENT)任一缺失都会导致静默失败。
- 忽略 setup.bash:Cyber RT 的动态库与工具依赖环境变量,未
source cyber/setup.bash时会出现找不到 libcyber.so 或 cyber_launch 命令。 - Bazel 缓存污染:切换分支或修改依赖后,建议
bazel clean --expunge后重新构建,避免旧缓存导致链接错误。 - 通道名不一致:Talker 写
/apollo/test,Listener 读/apollo/test,大小写、斜杠、命名空间必须完全一致。 - 容器内外路径混淆:Docker 中挂载的源码路径与宿主机不同,DAG 中的相对路径需以容器内工作目录为基准。
cyber_channel list 为空,优先检查组件是否真正启动、DAG 是否加载成功,而不是反复重装依赖。多数“环境问题”实际是配置问题。完成本节后,你应拥有一个可编译、可运行、可观测的 Cyber RT 环境,并能通过 Talker/Listener 示例验证通道通信。后续的组件开发、通道参数配置与 DAG 调度,都将在这个最小闭环之上逐步展开。