Files
MeowOS-For-R3P2/patch_v2/meow_audiod/build_audiod.sh
T
AskaEth d36a3a02a6 fix(audiod): build_audiod.sh 评审 P2 两条 — CC 单一命令词 + ZIG guard 下沉;顺手两处可见性
评审 r2(p2-2items/merge,reviewed 234b4d1)两条:

① P2-1 `CC="zig cc --target=mipsel-linux-musleabi"` 是死代码:多词整串存进变量,`"$CC"`
   按一个命令名展开 → `command not found`(评审实测 exit 127)。**M51 在 git worktree 里跑
   必踩**(`$ROOT/.tools/zig-mipsel-cc` 基本不存在 → 走 PATH 回退 → meow_audio 编不出来,
   而 meow_audio 正是 M43 带 time32 的那个 CLI)。
   - `CC` 只存**单个命令词**,多词 target flags 另放 `CC_EXTRA`(未加引号展开,故意分词);
   - PATH 回退改为 `CC="$(command -v zig)"` + `CC_EXTRA="cc --target=mipsel-linux-musleabi"`;
   - cli 分支加 `[ -n "$CC" ] || { 明确提示 CC=/ZIG= 或把 zig 放进 PATH; exit 1; }`——
     缺编译器时是**清晰错误**,不再是 command not found。

② P2-2 `[ -n "$ZIG" ] || exit 1` 放得太早:`$ZIG` 只有 audiod 目标用,却在 host/cli 分支之前,
   没有 zig 的机器上 `build_audiod.sh host`(只需宿主 cc)会被无谓打断。guard 下沉到 audiod
   段(MAIN 之后、LIBBT 之前),提示语也改成「audiod 目标需要它」。

顺带(评审附带观察):
③ host 目标不再用「先编一次 2>/dev/null、失败再编一次」兜底——那会把成功路径的 warning 吞掉。
   改成先跑一个 trivial 链接探针决定 `AS_LINK`(`-l:libasound.so.2` 或 `-lasound`),真正的编译
   全程保留 stderr。
④ `libasound.so.2.0.0 not found` 现在**列出试过的全部路径** + 覆盖语法(M51 在陌生环境里的
   唯一路标)。同时把 MAIN 的推导改成「git 不可用就留空」,避免产生 `/`、`$HOME` 这类伪候选。

自证(本 worktree 真跑):
- `ROOT=/nonexistent ./build_audiod.sh cli` → 正常出件 88888B/md5 3909c8d2…(评审的复现命令)
- PATH 里没有 zig → cli:`!! mipsel CC 未找到:设置 CC=…`(不再 command not found);
  audiod:`!! zig not found(audiod 目标需要它)…`
- PATH 里没有 zig → **host 目标照常 4 个产物 + test_bt_dev 71/71 + test_audiod_host 109/0**
- 正常环境两目标产物**一字未变**:meow_audiod 68604B/md5 9f58b219…、meow_audio 88888B/md5 3909c8d2…
- `test_time32_abi.sh --builds` ALL PASS,`build meow_audio src=yes macro=yes`
2026-11-11 20:05:49 +08:00

138 lines
8.4 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# build_audiod.sh — meow_audiod 交叉编译(mipsel glibc-dynamic)+ 宿主多目标可选。
#
# 目标:R3 Pro II / MeowOS(MIPS32 o32,真实 ABI)。audiod 复用 meow_ipc.h(共享协议头,
# -I../meow_launcherd)。audiod 为 svcd 托管的独立守护;meow_audio 为用户侧 CLI。
#
# 【P2 蓝牙链接定案 2026-09-03】设备为 glibc-2.22(ld-2.22.so / libc-2.22.so,非 musl),且
# libasound 会在运行时 dlopen 单独的 bluealsa pcm 插件(/usr/lib/alsa-lib/libasound_module_pcm_bluealsa.so)
# ——故 audiod 必须以**动态 glibc** 形态链接设备现有 libasound.so.2:
# - 用 zig --target=mipsel-linux-gnueabihf.2.22(硬浮点 o32,glibc-2.22 版本引用,设备 libs 齐);
# libasound 原型在 meow_audiod.c 内联声明(不依赖 asoundlib.h)。
# - 删 -static:musl-static 无 dlopen(实测 "Dynamic loading not supported",无法加载 bluealsa 插件);
# musl-dynamic 需设备不存在的 musl ld.so。libasound 链接库来自 libbt/(设备 libasound.so.2 副本)。
# - meow_audio CLI 无 libasound 依赖,保持 musl-static(zig-mipsel-cc)。
#
# 用法:
# ./build_audiod.sh # 交叉编译 → meow_audiod(mipsel glibc-dynamic,BT 直链 libasound)
# ./build_audiod.sh cli # 交叉编译 meow_audio CLI → meow_audio(mipsel musl-static)
# ./build_audiod.sh host # 宿主编译 *_host 并跑 test_audiod_host 回归(FILE sink)
#
# M50 蓝牙输出端到端:audiod 不再读写 /usr/data/alsa.conf(那是 HiBy 播放器的数据文件、语法非法、
# libasound 从不加载),改为 snd_pcm_open("bluealsa:DEV=<mac>,PROFILE=a2dp,CODEC=<token>")
# 内联参数(对应 /etc/alsa/conf.d/20-bluealsa.conf 的 pcm.bluealsa @args),失败必回落 DAC。
#
# 环境变量覆盖:ROOT / REPO 自动推导,ZIG / CC / LIBBT / ASOUND_SRC / CC_HOST 可显式指定。
set -e
cd "$(dirname "$0")"
# ---- 路径解析(M50:全部可被环境变量覆盖,不再硬绑某台机器的目录布局)----
# ROOT 只用于可选的历史路径(旧 .tools/zig-env、hiby_os_crack 解包树);缺省布局下不依赖它。
ROOT="${ROOT:-$HOME/Project/R3ProII}"
REPO="$(cd "$(dirname "$0")/../.." && pwd)" # 仓库根(worktree 亦可)
# mipsel 静态 CC:显式 CC → 历史 zig 包装脚本 → PATH 里的 zig(裸 zig 要另带 target flags)。
# ⚠️ CC **只存单个命令词**:`"$CC"` 是按一个命令名展开的,把 "zig cc --target=..." 整串存进去
# 会变成「找不到名叫 zig cc --target=... 的命令」(评审 P2-1,M51 在 worktree 里必踩)。
# 多词 flags 走 CC_EXTRA(未加引号展开,故意按空白分词),与下面 ZIG 的写法保持一致。
CC="${CC:-}"
CC_EXTRA=""
if [ -z "$CC" ]; then
if [ -x "$ROOT/.tools/zig-mipsel-cc" ]; then
CC="$ROOT/.tools/zig-mipsel-cc" # 历史包装脚本(内部已带 --target)
elif command -v zig >/dev/null 2>&1; then
CC="$(command -v zig)"
CC_EXTRA="cc --target=mipsel-linux-musleabi"
fi
fi
# 交叉编译用的 zig:显式 ZIG → 历史 zig-env → PATH。
ZIG="${ZIG:-}"
if [ -z "$ZIG" ]; then
if [ -x "$ROOT/.tools/zig-env/bin/zig" ]; then ZIG="$ROOT/.tools/zig-env/bin/zig"; else ZIG="$(command -v zig || true)"; fi
fi
INC="-I$REPO/patch_v2/meow_launcherd" # 共享协议头(相对仓库根,不再绑 ROOT)
# 注:$ZIG 只有 audiod 目标用;guard 放在 audiod 段之前(见下),host/cli 不因缺 zig 而中断。
if [ "$1" = "host" ]; then
HOST_CC="${CC_HOST:-cc}"
# BT 目标直链宿主 libasound(无 asoundlib.h,原型内联于 meow_audiod.c)。删 -ldl:BT 不再用 dlopen。
# 链接名先用「trivial 探针」决定:有 -l:libasound.so.2(精确版本)就用它,否则退 -lasound。
# 用探针而**不是**「先编一次、失败再编一次 2>/dev/null」——后者会把成功路径的 warning 一起吞掉。
AS_LINK="-l:libasound.so.2"
if ! printf 'int main(void){return 0;}\n' | "$HOST_CC" -x c - -o /dev/null "$AS_LINK" 2>/dev/null; then
AS_LINK="-lasound"
fi
"$HOST_CC" $INC -Os -Wall -Wextra meow_audiod.c bt_dev.c -o meow_audiod_host -lpthread $AS_LINK
"$HOST_CC" $INC -Os -Wall -Wextra meow_audio.c -o meow_audio_host -lm
"$HOST_CC" $INC -Os -Wall -Wextra test_audiod_host.c -o test_audiod_host -lm
"$HOST_CC" -Os -Wall -Wextra test_bt_dev.c bt_dev.c -o test_bt_dev -lm
echo "== host builds =="
ls -la meow_audiod_host meow_audio_host test_audiod_host test_bt_dev
file meow_audiod_host meow_audio_host test_audiod_host test_bt_dev
echo "== host regression (test_bt_dev: BT DEV auto-detect) =="
./test_bt_dev || { echo "!! test_bt_dev FAILED"; exit 1; }
echo "== host regression (test_audiod_host) =="
./test_audiod_host || { echo "!! host regression FAILED"; exit 1; }
exit 0
fi
if [ "$1" = "cli" ]; then
[ -n "$CC" ] || {
echo "!! mipsel CC 未找到:设置 CC=/path/to/zig 或 CC=/path/to/zig-mipsel-cc(或把 zig 放进 PATH)" >&2
exit 1; }
# M43: meow_audio 是 musl-static(当前 zig 链),与其它系统组件同源受损 → 链 time32 修
# clock_gettime/usleep(monitor 的 100ms 窗口/轮询)。
"$CC" $CC_EXTRA $INC -Os -Wall -Wextra -static -DMEOW_TIME32_LIBC_OVERRIDES \
meow_audio.c ../sdk/meow_time32.c -o meow_audio -lm
echo "== meow_audio (mipsel static CLI) =="
ls -la meow_audio
md5sum meow_audio
file meow_audio
exit 0
fi
# meow_audiod:mipsel glibc-dynamic,BT 直链 libasound(-Llibbt -lasound)。-lpthread 供播放线程。
# M43 例外:本目标走 glibc-2.22(time_t 32 位、timespec 8 字节)→ 无 musl time64 头/实现错位;
# 当前钉在 fw_content.conf 的出货件则是旧工具链静态 musl,其 4403→ENOSYS→4263+宽度转换本身健康。
# 两种形态都不需要 meow_time32.c(其 __clock_* 接管针对 zig musl 内部符号)。musl-static 的
# meow_audio CLI 已链 time32。
# 链接源 libbt/libasound.so.2.0.0(设备固件 libasound.so.2 副本);缺失时从固件树自拷贝(idempotent)。
# M50:LIBBT / ASOUND_SRC 可被环境变量覆盖;ASOUND_SRC 候选按「显式 → 历史解包树 → 仓内固件基线」
# 顺序取第一个存在的(旧值 $ROOT/hiby_os_crack/... 在多数 checkout 里不存在,set -e 下会直接卡住构建)。
# MAIN = 主 checkout 根(在 git worktree 里运行时,devdocs/ 与 fw_apps/ 这类未入库的固件树
# 只在主 checkout 里;git-common-dir 指向 <main>/.git,其父目录即主 checkout)。普通 checkout 下 == REPO。
MAIN=""
_gcd="$(git rev-parse --git-common-dir 2>/dev/null)" && MAIN="$(cd "$_gcd/.." 2>/dev/null && pwd)" || MAIN=""
[ -n "$ZIG" ] || {
echo "!! zig not found(audiod 目标需要它):设置 ZIG=/path/to/zig 或把 zig 放进 PATH" >&2
exit 1; }
LIBBT="${LIBBT:-libbt}"
if [ -z "$ASOUND_SRC" ]; then
tried=""
for c in "$ROOT/hiby_os_crack/r3proii/squashfs-root-example/usr/lib/libasound.so.2.0.0" \
"$REPO/devdocs/fw-baseline/squashfs-root/usr/lib/libasound.so.2.0.0" \
"$REPO/fw_apps/build/squashfs-root/usr/lib/libasound.so.2.0.0" \
${MAIN:+"$MAIN/devdocs/fw-baseline/squashfs-root/usr/lib/libasound.so.2.0.0"} \
${MAIN:+"$MAIN/fw_apps/build/squashfs-root/usr/lib/libasound.so.2.0.0"}; do
[ -f "$c" ] && { ASOUND_SRC="$c"; break; }
tried="$tried
- $c"
done
fi
[ -n "$ASOUND_SRC" ] && [ -f "$ASOUND_SRC" ] || {
echo "!! libasound.so.2.0.0 not found. 试过这些路径:$tried" >&2
echo " 覆盖方式:ASOUND_SRC=/path/to/libasound.so.2.0.0 $0" >&2
exit 1; }
mkdir -p "$LIBBT"
if [ ! -f "$LIBBT/libasound.so.2.0.0" ]; then cp "$ASOUND_SRC" "$LIBBT/libasound.so.2.0.0"; fi
ln -sf libasound.so.2.0.0 "$LIBBT/libasound.so"
ln -sf libasound.so.2.0.0 "$LIBBT/libasound.so.2"
"$ZIG" cc --target=mipsel-linux-gnueabihf.2.22 $INC -Os -Wall -Wextra meow_audiod.c bt_dev.c -o meow_audiod \
-lpthread -L"$LIBBT" -lasound
echo "== meow_audiod (mipsel glibc-dynamic, BT links libasound.so.2) =="
ls -la meow_audiod
md5sum meow_audiod
file meow_audiod
echo "-- dynamic NEEDED --"
readelf -d meow_audiod 2>/dev/null | grep -iE "needed" || true
echo "-- glibc version refs (max must be <= 2.22) --"
readelf --version-info meow_audiod 2>/dev/null | grep -oE "GLIBC_2\.[0-9]+" | sort -uV | tail -3 || true