经过排查:
[lxf@in-dev-docker:/]$ ll /opt/apollo/neo/lib/modules/planning/planning_component/libplanning_component.so
-rwxr-xr-x 1 lxf lxf 859624 Apr 21 14:36 /opt/apollo/neo/lib/modules/planning/planning_component/libplanning_component.so*
[lxf@in-dev-docker:/]$ ll /apollo_workspace/dev/install/apollo/modules/planning/planning_component/libplanning_component.so
-rw-r--r-- 1 lxf lxf 40 Apr 18 17:02 /apollo_workspace/dev/install/apollo/modules/planning/planning_component/libplanning_component.so
[lxf@in-dev-docker:/]$ ^C
[lxf@in-dev-docker:/]$ ll /apollo_workspace/.cache/bazel/679551712d2357b63e6e0ce858ebf90e/execroot/__main__/bazel-out/k8-opt/bin/modules/planning/planning_component/libplanning_component.so
-r-xr-xr-x 1 lxf lxf 859624 Apr 21 15:58 /apollo_workspace/.cache/bazel/679551712d2357b63e6e0ce858ebf90e/execroot/__main__/bazel-out/k8-opt/bin/modules/planning/planning_component/libplanning_component.so*
[lxf@in-dev-docker:/]$ ll /opt/apollo/neo/lib/modules/planning/planning_component/libplanning_component.so
-rwxr-xr-x 1 lxf lxf 859624 Apr 21 14:36 /opt/apollo/neo/lib/modules/planning/planning_component/libplanning_component.so*
[lxf@in-dev-docker:/]$ ll /apollo_workspace/dev/install/apollo/modules/planning/planning_component/libplanning_component.so
-rw-r--r-- 1 lxf lxf 40 Apr 18 17:02 /apollo_workspace/dev/install/apollo/modules/planning/planning_component/libplanning_component.so
[lxf@in-dev-docker:/]$ ll /apollo_workspace/.cache/bazel/679551712d2357b63e6e0ce858ebf90e/execroot/__main__/bazel-out/k8-opt/bin/modules/planning/planning_component/libplanning_component.so
-r-xr-xr-x 1 lxf lxf 859624 Apr 21 16:54 /apollo_workspace/.cache/bazel/679551712d2357b63e6e0ce858ebf90e/execroot/__main__/bazel-out/k8-opt/bin/modules/planning/planning_component/libplanning_component.so*
[lxf@in-dev-docker:/]$
排查
apollo中编译planning模块之后libplanning_component.so产生在/apollo_workspace/.cache/bazel/679551712d2357b63e6e0ce858ebf90e/execroot/main/bazel-out/k8-opt/bin/modules/planning/planning_component/目录下,执行dreamview的时候,dreamview调用的库在/opt/apollo/neo/lib/modules/planning/planning_component/目录下,我想你编译之后就可以在dreamViw使用,应该怎么操作?
回答
在 Apollo 系统中,编译生成的 libplanning_component.so
默认会存储在 Bazel 的缓存目录中,但 Dreamview 运行时会从 /opt/apollo/neo/lib
等预定义路径加载依赖库。若希望新编译的库能被 Dreamview 使用,需手动或通过构建系统将库文件部署到目标路径。以下是具体操作步骤及原理分析:
一、问题原因分析
- Bazel 默认输出路径与运行时路径不一致
- Bazel 构建生成的库文件(如
libplanning_component.so
)默认存储在临时缓存目录(如/.cache/bazel
),而 Apollo 运行时(包括 Dreamview)会从预定义的安装目录(如/opt/apollo/neo/lib
)加载库文件 。 - 若未手动同步这两个路径,Dreamview 将继续使用旧版本库文件。
- Bazel 构建生成的库文件(如
二、解决方案
方法 1:手动复制库文件(快速验证)
# 步骤 1:停止正在运行的 Apollo 和 Dreamview
./scripts/bootstrap.sh stop
# 步骤 2:将新编译的库复制到目标目录
sudo cp -f /apollo_workspace/.cache/bazel/.../libplanning_component.so /opt/apollo/neo/lib/modules/planning/planning_component/
# 步骤 3:重启 Dreamview
./scripts/bootstrap.sh start
- 优点:操作简单,适合快速测试新库功能。
- 缺点:每次重新编译后需重复操作,未与构建系统集成。
方法 2:通过 Bazel 规则指定输出路径(推荐)
修改 Planning 模块的 BUILD
文件,添加自定义安装规则:
# 在 modules/planning/planning_component/BUILD 文件中添加:
load("@rules_pkg//:pkg.bzl", "pkg_install")
pkg_install(
name = "install_planning_component",
srcs = [":libplanning_component.so"],
dest = "/opt/apollo/neo/lib/modules/planning/planning_component/",
visibility = ["//visibility:public"],
)
执行构建命令时附加安装目标:
bazel build //modules/planning/planning_component:install_planning_component
- 原理:通过 Bazel 的
pkg_install
规则将构建产物自动部署到目标路径 。 - 优点:与构建流程集成,无需手动操作。
- 注意:需确保目标路径具有写入权限(可能需要
sudo
)。
方法 3:修改 Apollo 环境变量(临时调试)
通过 LD_LIBRARY_PATH
强制优先加载新库:
# 步骤 1:设置环境变量
export LD_LIBRARY_PATH=/apollo_workspace/.cache/bazel/.../:$LD_LIBRARY_PATH
# 步骤 2:重启 Dreamview
./scripts/bootstrap.sh restart
- 原理:动态链接器会优先从
LD_LIBRARY_PATH
指定的路径加载库 。 - 适用场景:临时调试,避免覆盖系统库。
- 缺点:环境变量需每次启动时重新设置。
方法 4:更新 Apollo 安装脚本(长期方案)
若 Apollo 项目提供了安装脚本(如 install.sh
),可修改脚本逻辑以包含新库的部署步骤。例如,在安装脚本中添加:
# 查找新编译的库文件并复制到目标路径
find /apollo_workspace/.cache/bazel -name "libplanning_component.so" -exec cp {} /opt/apollo/neo/lib/modules/planning/planning_component/ \;
- 优点:一劳永逸,适合持续开发环境。
- 注意:需熟悉 Apollo 的部署脚本结构,避免破坏其他依赖。
三、验证操作
- 检查库版本
# 查看目标路径下的库文件修改时间 ls -l /opt/apollo/neo/lib/modules/planning/planning_component/libplanning_component.so
- 观察 Dreamview 日志
若日志中无tail -f /apollo/data/log/dreamview.INFO
Failed to load library
错误,则说明新库已生效。
四、注意事项
- 权限问题:操作
/opt/apollo/neo
目录可能需要sudo
权限。 - 依赖更新:若 Planning 模块依赖其他组件(如
common
或cyber
),需同步更新相关库文件。 - 版本一致性:确保新编译的库与其他模块的接口版本兼容,避免因 ABI 不匹配导致崩溃 。
通过以上方法,可确保新编译的 libplanning_component.so
被 Dreamview 正确加载,从而测试最新的规划算法或功能修改。
简单解决构建软连接
要创建软连接,可以使用以下命令格式:
ln -s [源文件或目录] [目标文件或目录]
在使用此命令时,需要注意不要在源文件或目录的路径后加上斜杠(/)。例如,要在当前路径下创建一个名为test的软连接,指向/var/www/test目录,可以使用以下命令:
ln -s /var/www/test test
实际执行:
ln -s /apollo_workspace/.cache/bazel/679551712d2357b63e6e0ce858ebf90e/execroot/__main__/bazel-out/k8-opt/bin/modules/planning/planning_component/libplanning_component.so /opt/apollo/neo/lib/modules/planning/planning_component/libplanning_component.so