标题建议: [BUG] Qt 交叉编译 pipeline 静默吞掉致命失败:PulseAudio 未编出时仍报 "RootFS completed successfully!"
摘要
一次正常的镜像构建中,PulseAudio 因 host 缺少 meson 而编译失败,但整条 pipeline 没有报错中止,
反而一路打印成功,最终打出 RootFS completed successfully! 并开始 mke2fs 制作 SD 镜像,
直到手动 Ctrl-C 才停下。Qt 6.9.1 configure 阶段确实抛出了 ERROR: Feature "pulseaudio": Forcing to "ON" breaks its condition: WrapPulseAudio_FOUND,但该错误被上层捕获并降级为警告。
期望 vs 实际
- 期望:任一第三方库 / Qt 模块编译失败时,pipeline 立即中止并明确报错,绝不产出「假成功」的镜像。
- 实际:失败被两层
if cmd; then … else log_warn 静默吞掉,pipeline 继续推进并产出镜像。
触发现象(日志片段)
[INFO] PulseAudio enabled (FEATURE_pulseaudio=ON)
[INFO] FFmpeg enabled (FEATURE_ffmpeg=ON) with PulseAudio support
...
ERROR: Feature "pulseaudio": Forcing to "ON" breaks its condition:
WrapPulseAudio_FOUND
Condition values dump:
WrapPulseAudio_FOUND = "FALSE"
-- Configuring incomplete, errors occurred!
...
[ERROR] Configure failed
[ERROR] 阶段 5 失败: 编译 Target Qt
[WARN] ✗ install_qt_with_compile.sh failed (continuing anyway)
[INFO] Third-party installations completed
[INFO] RootFS completed successfully!
[CMD] mke2fs -t ext4 -d .../rootfs -L ROOTFS .../rootfs.ext4
而 PulseAudio 当时的构建日志只有一行(138 字节):
third_party/pulseaudio/builtin.sh: line 225: meson: command not found
根因分析
由两个独立缺陷叠加导致(任一单独修掉都能缓解,建议都修)。
缺陷 1:两层「静默吞失败」——set -e 对 if 条件豁免被滥用
set -euo pipefail 不会对出现在 if/while/||/&&/! 被测试位置上的命令触发退出。
本 pipeline 在两层都刻意用 if cmd; then … else log_warn(log_warn 返回 0)把致命失败降级为软警告:
- 第三方库安装层 —
third_party/qt-compile-pipeline/scripts/third_party/manager.sh 的 cmd_install:
if $install_func; then
third_party_mark_installed "$lib"
log_ok "${lib} installed successfully"
else
log_warn "${lib} installation failed" # ← 失败只 warn,返回 0;不打 .xxx-installed 标记
fi
结果:manager.sh 即使内部编译失败,最终仍 exit 0。
第三方安装脚本调度层 — scripts/varified_rootfs_ok.sh:332-336:
if bash "$script"; then # script = install_qt_with_compile.sh
log_info " ✓ $name completed"
else
log_warn " ✗ $name failed (continuing anyway)" # ← Qt 编译挂了也只 warn,循环继续
fi
雪上加霜:verify_rootfs(scripts/varified_rootfs_ok.sh:343 起)只校验 rootfs 目录是否存在,
不校验内容,于是打出 RootFS completed successfully!。
缺陷 2:FEATURE_pulseaudio 开关门控错误
third_party/qt-compile-pipeline/scripts/03-build-target-qt.sh:242:
if [[ -n "$PULSEAUDIO_LIB_PATH" ]]; then
CMAKE_PASS_ARGS+=("-DFEATURE_pulseaudio=ON")
fi
而 PULSEAUDIO_LIB_PATH 来自 common.sh:third_party_get_lib_path(52-77 行),该函数只要
sysroot 下的 usr/lib 目录存在就返回路径,与 PulseAudio 是否真正编译成功无关。
因此 PulseAudio 没编出来时,仍会给 Qt 喂 -DFEATURE_pulseaudio=ON,直接触发 Qt configure 的
Forcing to "ON" breaks its condition 硬错误。FFmpeg 同理(03-build-target-qt.sh:249)。
注:脚本里其实有一处「真正存在性」检查(03-build-target-qt.sh:167 的 -f libpulse.so),
但它只用于打印一条 info 日志,并未参与上面 FEATURE_pulseaudio=ON 的门控判定。
影响范围
任何第三方库(tslib/libsndfile/pulseaudio/ffmpeg/openssl)编译失败都不会中止 pipeline,产出残缺但「成功」的镜像。
Qt 交叉编译失败同样被吞,镜像照做,极易带着问题烧录到设备后才暴露。
本次具体诱因(host 缺 meson)已临时解决;但缺陷本身与 meson 无关,换任何诱因都会复现。
建议修复(待评估)
修门控(缺陷 2):FEATURE_pulseaudio / FEATURE_ffmpeg 的开关改为按「真正装好」来判定—— 读 .xxx-installed 标记,或 [[ -f .../libpulse.so ]];不满足则不传 -DFEATURE_*=ON(甚至显式 =OFF)。
修失败传播(缺陷 1):让第三方库与 Qt 编译的失败能真正中止 pipeline,而不是 continuing anyway。 至少在 set -e 之外,对关键步骤加一道明确的致命判定。
加强 verify_rootfs:校验关键产物(如 ${INSTALL_PREFIX}/bin/qmake、必需 .so)存在,而非只看目录。
相关文件 / 行号
third_party/qt-compile-pipeline/scripts/third_party/manager.sh(cmd_install,约 74-83 行)
third_party/qt-compile-pipeline/scripts/03-build-target-qt.sh(242、249 行;167 行的存在性检查未用于门控)
third_party/qt-compile-pipeline/scripts/third_party/common.sh(third_party_get_lib_path,52-77 行)
third_party/qt-compile-pipeline/scripts/third_party/pulseaudio/builtin.sh(225 行 meson 调用;331 行手写 .pc)
scripts/varified_rootfs_ok.sh(332-336 行第三方脚本调度;343 行起 verify_rootfs)
复现方式(拟)
标注为「拟」,待专门模拟时确认:临时破坏 PulseAudio 可构建性(如临时把 meson 移走 / 改坏 meson 调用),
跑完整 pipeline,确认当前会静默继续并产出镜像——作为修复前的回归基线。
标题建议: [BUG] Qt 交叉编译 pipeline 静默吞掉致命失败:PulseAudio 未编出时仍报 "RootFS completed successfully!"
摘要
一次正常的镜像构建中,PulseAudio 因 host 缺少
meson而编译失败,但整条 pipeline 没有报错中止,反而一路打印成功,最终打出
RootFS completed successfully!并开始mke2fs制作 SD 镜像,直到手动 Ctrl-C 才停下。Qt 6.9.1 configure 阶段确实抛出了
ERROR: Feature "pulseaudio": Forcing to "ON" breaks its condition: WrapPulseAudio_FOUND,但该错误被上层捕获并降级为警告。期望 vs 实际
if cmd; then … else log_warn静默吞掉,pipeline 继续推进并产出镜像。触发现象(日志片段)
[INFO] PulseAudio enabled (FEATURE_pulseaudio=ON)
[INFO] FFmpeg enabled (FEATURE_ffmpeg=ON) with PulseAudio support
...
ERROR: Feature "pulseaudio": Forcing to "ON" breaks its condition:
WrapPulseAudio_FOUND
Condition values dump:
WrapPulseAudio_FOUND = "FALSE"
-- Configuring incomplete, errors occurred!
...
[ERROR] Configure failed
[ERROR] 阶段 5 失败: 编译 Target Qt
[WARN] ✗ install_qt_with_compile.sh failed (continuing anyway)
[INFO] Third-party installations completed
[INFO] RootFS completed successfully!
[CMD] mke2fs -t ext4 -d .../rootfs -L ROOTFS .../rootfs.ext4
而 PulseAudio 当时的构建日志只有一行(138 字节):
third_party/pulseaudio/builtin.sh: line 225: meson: command not found
根因分析
由两个独立缺陷叠加导致(任一单独修掉都能缓解,建议都修)。
缺陷 1:两层「静默吞失败」——
set -e对if条件豁免被滥用set -euo pipefail不会对出现在if/while/||/&&/!被测试位置上的命令触发退出。本 pipeline 在两层都刻意用
if cmd; then … else log_warn(log_warn返回 0)把致命失败降级为软警告:third_party/qt-compile-pipeline/scripts/third_party/manager.sh的cmd_install:结果:manager.sh 即使内部编译失败,最终仍 exit 0。
第三方安装脚本调度层 — scripts/varified_rootfs_ok.sh:332-336:
if bash "$script"; then # script = install_qt_with_compile.sh
log_info " ✓ $name completed"
else
log_warn " ✗ $name failed (continuing anyway)" # ← Qt 编译挂了也只 warn,循环继续
fi
雪上加霜:verify_rootfs(scripts/varified_rootfs_ok.sh:343 起)只校验 rootfs 目录是否存在,
不校验内容,于是打出 RootFS completed successfully!。
缺陷 2:FEATURE_pulseaudio 开关门控错误
third_party/qt-compile-pipeline/scripts/03-build-target-qt.sh:242:
if [[ -n "$PULSEAUDIO_LIB_PATH" ]]; then
CMAKE_PASS_ARGS+=("-DFEATURE_pulseaudio=ON")
fi
而 PULSEAUDIO_LIB_PATH 来自 common.sh:third_party_get_lib_path(52-77 行),该函数只要
sysroot 下的 usr/lib 目录存在就返回路径,与 PulseAudio 是否真正编译成功无关。
因此 PulseAudio 没编出来时,仍会给 Qt 喂 -DFEATURE_pulseaudio=ON,直接触发 Qt configure 的
Forcing to "ON" breaks its condition 硬错误。FFmpeg 同理(03-build-target-qt.sh:249)。
注:脚本里其实有一处「真正存在性」检查(03-build-target-qt.sh:167 的 -f libpulse.so),
但它只用于打印一条 info 日志,并未参与上面 FEATURE_pulseaudio=ON 的门控判定。
影响范围
任何第三方库(tslib/libsndfile/pulseaudio/ffmpeg/openssl)编译失败都不会中止 pipeline,产出残缺但「成功」的镜像。
Qt 交叉编译失败同样被吞,镜像照做,极易带着问题烧录到设备后才暴露。
本次具体诱因(host 缺 meson)已临时解决;但缺陷本身与 meson 无关,换任何诱因都会复现。
建议修复(待评估)
修门控(缺陷 2):FEATURE_pulseaudio / FEATURE_ffmpeg 的开关改为按「真正装好」来判定—— 读 .xxx-installed 标记,或 [[ -f .../libpulse.so ]];不满足则不传 -DFEATURE_*=ON(甚至显式 =OFF)。
修失败传播(缺陷 1):让第三方库与 Qt 编译的失败能真正中止 pipeline,而不是 continuing anyway。 至少在 set -e 之外,对关键步骤加一道明确的致命判定。
加强 verify_rootfs:校验关键产物(如 ${INSTALL_PREFIX}/bin/qmake、必需 .so)存在,而非只看目录。
相关文件 / 行号
third_party/qt-compile-pipeline/scripts/third_party/manager.sh(cmd_install,约 74-83 行)
third_party/qt-compile-pipeline/scripts/03-build-target-qt.sh(242、249 行;167 行的存在性检查未用于门控)
third_party/qt-compile-pipeline/scripts/third_party/common.sh(third_party_get_lib_path,52-77 行)
third_party/qt-compile-pipeline/scripts/third_party/pulseaudio/builtin.sh(225 行 meson 调用;331 行手写 .pc)
scripts/varified_rootfs_ok.sh(332-336 行第三方脚本调度;343 行起 verify_rootfs)
复现方式(拟)
标注为「拟」,待专门模拟时确认:临时破坏 PulseAudio 可构建性(如临时把 meson 移走 / 改坏 meson 调用),
跑完整 pipeline,确认当前会静默继续并产出镜像——作为修复前的回归基线。