高通8155平台 T13T 分支编译实录:QNX 环境配置、模型仓准备与 Bazel 版本避坑
前言
这次主要梳理的是 高通 8155 平台 T13T 分支代码 的本地编译流程。
表面上看只是一次常规编译,实际过程中踩到的核心坑并不在 QNX SDK 本身,而在 模型仓前置准备、Bazel 版本兼容性,以及脚本真实行为和表面命令不完全一致。
最终验证下来,这套工程能够顺利编译的关键前提之一是:
- 先准备好
ims-perception-alg主仓和ims-models模型仓 - QNX SDK 环境变量配置正确
- 工程切到正确分支
- Bazel 降级到 5.4.1
- 理解
build_ims_t13t_qnx.sh实际会自动source env_setup.sh - 按固定顺序完成清理、拉分支、重新编译、最终打包
这篇文章除了保留完整命令链路,也把三个关键脚本里真正影响复现的逻辑一并补充进去,后面换机器、换环境、或者同事接手时都能直接复用。
一、工程背景
目标是编译 ims-perception-alg 仓库中的 T13T 分支代码,平台为:
- 芯片平台: Qualcomm 8155
- 目标平台: g7phr2
- 系统: QNX
- 工程路径:
~/hewu/01_project/ims_code/slimesdk/ims-perception-alg
编译前需要先完成代码仓准备和 SDK 环境初始化,然后再执行平台构建脚本。
二、前置准备:拉取 ims-perception-alg 和 ims-models 仓库
在正式编译 ims-perception-alg 之前,先准备主仓和模型仓:
1 | |
这一步的作用
这一步本质上是在编译前补齐工程运行/构建依赖所需的模型资源。
如果本地缺少这个仓库,后面的编译、打包或运行链路可能并不完整。
一个容易忽略的细节
你实际走通的命令里有:
1 | |
这说明项目最终希望在 desaysv/ds_ims 下看到的是 models/ 目录,而不是 ims-models/ 目录。
这类目录命名约定如果不对,常见后果不是立刻报错,而是后续运行或打包时找不到模型资源。
如果本地已经存在仓库
不要重复 clone,可以改成:
1 | |
如果历史上目录名还是 ims-models,要额外确认脚本当前到底读取 ims-models 还是 models。
三、QNX 环境初始化
完成模型仓准备后,回到工程根目录,执行环境配置脚本:
1 | |
参数说明
--sdk ../sv-g7phr2-qnx-system-sdk
指定 QNX SDK 路径--platform g7phr2
指定目标平台--os qnx
指定目标操作系统
这里踩到的第一个坑
一开始容易直接用 sh 去跑脚本,结果报错:
1 | |
原因是 env_setup.sh 文件首行虽然写的是:
1 | |
但脚本内部实际用了 bash 风格函数定义:
1 | |
所以这里必须显式使用:
1 | |
这也是一个典型“shebang 和脚本语法不一致”的坑。
四、env_setup.sh 脚本到底做了什么
只看命令行,很容易以为 env_setup.sh 只是简单导出几个变量;但从脚本内容看,它实际上做了几类关键工作。
4.1 平台识别
脚本会根据 --platform 参数识别当前目标平台,例如:
g7phr2/8155→ QNX + Qualcomm 81558255→ QNX + Qualcomm 8255pc→ PCam62a→ TI Linuxandroid→ Android
其中 g7phr2 会落到:
IS_QNX=trueIS_QCOM_8155=true
并最终设置:
1 | |
4.2 自动 source QNX SDK 环境
对于 8155 / g7phr2,脚本会执行:
1 | |
这一步会把 QNX 编译链相关环境变量灌进当前 shell,包括:
QNX_HOSTQNX_TARGET- 相关交叉工具链路径
4.3 自动重写 .bazelrc
脚本里有一条很关键的动作:
1 | |
也就是说,每次跑 env_setup.sh,当前工程根目录下的 .bazelrc 都可能被重新生成。
后面针对平台的 crosstool_top、cpu、action_env、linkopt 等配置,都是在这个基础上继续 echo >> .bazelrc 追加进去的。
4.4 为 8155 平台追加 QNX 构建配置
对于 8155 / g7phr2,脚本会追加类似配置:
1 | |
同时还会把以下路径写入 link 选项:
mediapipe/util/snpe/install/lib/aarch64-qnx-gcc5.4toolchain/opencv_qnx/libdesaysv/3rdparty/slimecv/qualcomm/qnx/qnx700/fastcv/v1.8.2/lib- QNX 系统库路径
这也是为什么环境脚本不是“可有可无”的,它实际上在帮 Bazel 拼完整个平台 toolchain 和链接路径。
五、首次编译尝试
环境配置完成后,先执行一次 Debug 编译:
1 | |
参数说明:
-d:Debug 模式-r:Release 模式-c:先执行bazel clean --expunge-l:使用本地工具链路径-h:查看帮助
build_ims_t13t_qnx.sh 的真实行为
这个脚本表面看是一个 T13T 编译脚本,但它内部还做了几件很关键的事:
1)自动保护环境重复初始化
脚本使用了一个环境保护变量:
1 | |
如果没有设置,它会自动执行:
1 | |
这意味着:
- 你可以先手动跑
env_setup.sh - 也可以只跑 build_ims_t13t_qnx.sh,让它自己初始化环境
但在同一个 shell 里重复执行时,它会尽量避免重复 source。
2)Debug / Release 底层调用不同
Debug 模式时,脚本实际调用:
1 | |
Release 模式时,实际调用:
1 | |
也就是说,这个脚本不仅编译,还会自动打包。
3)脚本会先删除旧打包目录
编译前会执行:
1 | |
所以如果你之前手工修改过 ds_ims 目录里的内容,重新跑脚本时会被直接清掉。
六、真正卡住的问题:Bazel 版本不兼容
这次编译过程中,真正的核心问题不是业务代码,而是 Bazel 版本漂移。
6.1 初始现象
最初机器上的 Bazel 版本较新,构建时出现类似报错:
1 | |
以及:
1 | |
这类问题通常意味着:
- 工程依赖仍使用旧版 Bazel 的平台约束写法
- 当前本机 Bazel 版本过高
- 构建系统与项目年代不匹配
6.2 排查结论
最终验证结果是:
- Bazel 7.4.1:不兼容
- Bazel 6.5.0:仍然有兼容问题
- Bazel 5.4.1:可以编译
也就是说,这个工程要稳定构建,当前应固定在:
1 | |
七、切换 Bazel 5.4.1
7.1 下载 Bazel 5.4.1
1 | |
7.2 增加执行权限
1 | |
7.3 将本地 bazel 命令切换到 5.4.1
1 | |
7.4 刷新 shell 命令缓存
1 | |
7.5 确认版本
1 | |
预期输出:
1 | |
八、清理缓存并重新编译
切换 Bazel 后,建议先清理缓存:
1 | |
然后重新执行编译:
1 | |
这样可以避免旧版本 Bazel 的缓存污染当前构建流程。
如果想把 clean 动作交给脚本内部统一完成,也可以直接:
1 | |
九、同步最新 T13T 分支代码
为了确保本地代码和远端一致,这次还进行了分支切换和更新。
9.1 查看远端信息
1 | |
9.2 切换到 T13T 开发分支
1 | |
9.3 拉取远端最新代码
1 | |
完成后再次执行编译:
1 | |
十、package_binary_8155.sh 实际打包了什么
编译成功后,执行二进制打包:
1 | |
但从脚本内容看,这个打包动作并不是简单地压缩几个 bin 文件,而是按固定目录结构组装一整套可运行内容。
10.1 常用参数语义
-m t13t:指定项目/模块名为t13t-a:打入精度统计相关 pbtxt 和脚本-v:包含 videocard 相关内容-l:使用本地工具链 strip 路径-r:Release 打包
10.2 输出目录结构
脚本最终生成的输出目录固定为:
1 | |
并在其中创建以下目录:
bin/lib/etc/etc/calibration/etc/compare/etc/statistic/models/models/labels/data/output/hexagon/
最终还会打包为:
1 | |
10.3 会写入版本信息
脚本会自动生成:
1 | |
其中包含:
- Git commit 简短 ID
- Git commit 时间
- 最近一次 merge message
- 本次打包时间
这对后续板端版本追踪、问题回溯很有用。
10.4 T13T 模块会额外复制哪些资源
对于 t13t,脚本会额外复制:
desaysv/ds_ims/custom/t13t/*.cfgdesaysv/ds_ims/custom/t13t/*.pbtxtdesaysv/ds_ims/custom/t13t/*.shdesaysv/ds_ims/models/distracted_config/*→etc/calibration/desaysv/ds_ims/models/snpe→models/desaysv/ds_ims/models/labels/*.txt→models/labels/desaysv/ds_ims/models/static→models/
这意味着 T13T 的运行不只依赖二进制本身,还依赖一整套配置、模型和标注资源。
10.5 实际打进包里的核心二进制/库
脚本会尝试从 bazel-bin 拷贝这些内容:
sva.alg.dmssva.alg.omssva.alg.strlibds_ims_perception.soims_data_emulate_ppssnpe_inference
同时还会复制运行依赖库,例如:
libdsvrtsdk.solibDesaysv_SlimeCV.solibDesaysv_Perf.sotoolchain/opencv_qnx/lib/lib*third_party/lib-svpps/lib/lib*libDsImsFastcv.solibfastcvopt.so
10.6 一个很实际的结论
8155 平台这套打包逻辑,明显不是“把编译产物扔一起”那么简单,而是已经带有明显的板端部署包拼装脚本属性。
所以后续如果出现“编译成功但板端运行失败”,优先不能只盯编译日志,还要检查:
- 模型目录是否齐全
- pbtxt/cfg/sh 是否打进去
- 依赖 so 是否完整
- calibration / statistic / compare 目录是否缺文件
十一、本次完整命令链路
下面是本次实际走通的命令顺序:
1 | |
十二、经验总结
这次编译最值得记录的,不是“命令怎么敲”,而是下面这几个判断。
1. 模型仓准备要放在最前面
ims-models 不是一个可有可无的附属仓库,而是整个编译/运行链路中的前置依赖之一。
如果缺它,后面即使主工程代码拉下来了,也可能并不能完整跑通。
2. shebang 不能全信,要看脚本真实语法
env_setup.sh 明明写了 #!/bin/sh,但实际用了 bash 语法。
这种脚本最容易在换环境时莫名其妙报错,所以要优先怀疑“是不是 shell 不对”。
3. 先判断是环境问题,还是构建系统问题
QNX 环境变量正常,并不代表一定能编译成功。
如果 Bazel 在 analysis 阶段报平台约束相关错误,优先怀疑 Bazel 版本兼容性。
4. 老工程不要默认用新 Bazel
对于带有以下特征的工程:
WORKSPACEMODULE.bazel- MediaPipe / TensorFlow Lite 相关依赖
- QNX 交叉编译
- 历史构建负担较重
很容易出现“代码没问题,但 Bazel 太新”的情况。
5. build_ims_t13t_qnx.sh 实际上是“编译+打包”总控脚本
它不是单纯 build 脚本,而是同时负责:
- 必要时自动 source 环境
- 触发底层
build_8155.sh - 调用
package_binary_8155.sh - 清理旧的
ds_ims输出目录
所以日常使用时,最好把它理解为“主入口脚本”。
6. 固定版本非常重要
建议后续在工程根目录补充:
1 | |
这样后面换机器或换人接手时,版本漂移问题会少很多。
7. 编译前最好固定一个标准动作序列
建议后续统一为:
- 准备
ims-perception-alg - 准备
ims-models并确认目录名 - 配置 SDK 环境
- 确认 Bazel 版本
- 清理缓存
- 切换目标分支
- 拉取最新代码
- 编译
- 打包
- 检查
ds_ims/目录和ds_ims.tar.gz
这样能显著减少“环境脏状态”导致的随机问题。
十三、后续还值得继续补强的点
这篇记录目前已经能支持复现,但后续还可以继续补强:
script/build_8155.sh的内部编译目标说明-d -e这组参数在底层脚本中的具体含义sva.alg.dms / oms / str三个二进制的职责划分ds_ims.tar.gz解包后的板端部署方式- T13T 与 T13C 的配置差异
models/目录的最小必需文件集- 是否需要固定更多工具链版本(例如 Python、SNPE、QNX SDK 子版本)
总结
这次高通 8155 平台 T13T 分支的编译最终能够打通,核心经验很明确:
- 先准备好 ims-perception-alg 和 ims-models
ims-models最终目录名要和工程约定一致- QNX 环境脚本要用 bash
- 分支要切对并同步远端最新代码
- Bazel 必须降到 5.4.1
- 编译前最好执行一次
bazel clean --expunge - 要知道
build_ims_t13t_qnx.sh实际会自动打包 - 编译成功后还要检查
ds_ims目录是否包含完整部署内容
对这类有历史构建负担的工程来说,“版本对齐”往往比“代码修复”更重要。
而对板端交付链路来说,“打包内容是否完整”又往往比“编译是否成功”更关键。
把这条链路沉淀下来,后面无论是换机器、重装环境,还是团队内部交接,都会省下很多排查时间。
附:本次关键命令清单
1 | |