#!/bin/bash # rebuild_binaries.sh — 重编「进固件的那批组件」,产物就地写回 patch_v2/<组件>/(M51 批次)。 # # 为什么需要它:各组件自己的 build_*.sh 里仍散落着本机布局的默认路径 # (`$HOME/Project/R3ProII/.tools/...`、`$HOME/.tools/mipsel-linux-muslsf-cross/...`), # 在干净 checkout / git worktree 里直接跑会「找不到编译器」。本脚本**不改那些脚本**, # 而是在调用侧把这些路径补齐:造一个兼容 HOME,其中 # $COMPAT_HOME/Project/R3ProII/.tools -> 真 .tools(zig-mipsel-cc / muslsf sysroot) # $COMPAT_HOME/Project/R3ProII/patch_v2 -> 本 checkout 的 patch_v2 # 于是历史硬编码路径落到当前 checkout 与真工具链,干净 worktree 也能直接编。 # # 需要但不在 git 里的两件东西(都会被自动找/校验): # patch_v2/sdk/meow_ui.a 被 .gitignore 忽略(launcherd 链它)。默认从**主 checkout** 取 # (git rev-parse --git-common-dir 的父目录,M50 在 build_audiod.sh 用同法); # 在普通 checkout 里 == 本 checkout。取不到会报错并列出试过的路径。 # devdocs/fw-baseline/… audiod 链接用的设备 libasound.so.2 副本;build_audiod.sh 自己会回退主 checkout。 # # 环境变量覆盖: # ZIGCC mipsel-musl 交叉编译器(单个命令词;默认 $HOME/.tools/zig-mipsel-cc) # ZIG 裸 zig(audiod 守护目标用;默认 PATH 里的 zig) # MEOW_UI_A_SRC meow_ui.a 来源(默认主 checkout 的 patch_v2/sdk/meow_ui.a) # MEOW_UI_A_MD5 期望的 meow_ui.a md5(默认 m51 批次的 cc0ed49b…;不符只告警不阻断) # COMPAT_HOME 兼容 HOME 目录(默认 ${TMPDIR:-$HOME/tmp}/meow-build-home) # # 用法: # bash scripts/build/rebuild_binaries.sh # 全部 5 组 # bash scripts/build/rebuild_binaries.sh bootmenu # 只编指定的(可多个) # 组件名:bootmenu netmgrd audiod audio launcherd set -u ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" MEOW_UI_A_MD5="${MEOW_UI_A_MD5:-cc0ed49bdaa43a9867408b41b6311c28}" die() { echo "!! $*" >&2; exit 1; } # ---- 工具链:必须是「单个命令词」------------------------------------------------ # 组件脚本用 "$CC" 调用,把 "zig cc --target=..." 整串塞进变量会变成 # 「找不到名叫 zig cc --target=... 的命令」(exit 127)。M50 在 build_audiod.sh 里 # 用 CC + CC_EXTRA 修过同类 bug;这里显式挡住,并给出可执行的建议。 ZIGCC="${ZIGCC:-$HOME/.tools/zig-mipsel-cc}" ZIG="${ZIG:-$(command -v zig || true)}" case "$ZIGCC" in *[[:space:]]*) die "ZIGCC 里不能带空格/参数:'$ZIGCC' 组件脚本按单个命令词调用它。请用包装脚本,或设 ZIGCC=$HOME/.tools/zig-mipsel-cc" ;; esac [ -x "$ZIGCC" ] || die "找不到可执行的交叉编译器 ZIGCC='$ZIGCC' 试过:\$ZIGCC、\$HOME/.tools/zig-mipsel-cc($HOME/.tools/zig-mipsel-cc) 覆盖方式:ZIGCC=/path/to/zig-mipsel-cc bash $0" [ -n "$ZIG" ] && [ -x "$ZIG" ] || die "找不到 zig(audiod 守护目标需要它) 覆盖方式:ZIG=/path/to/zig bash $0" # ---- 主 checkout(worktree 里 meow_ui.a / devdocs/ / fw_apps/ 只在主 checkout)---- # git rev-parse --git-common-dir 在 linked worktree 里给出**主仓库**的 .git 路径(绝对), # 其父目录就是主 checkout 根;普通 checkout 下它给 ".git",拼到 $ROOT 后同理。 # (M50 在 build_audiod.sh 里用的就是这个口径:MAIN="$(cd "$_gcd/.." && pwd)") MAIN="$ROOT" _gcd="$(git -C "$ROOT" rev-parse --git-common-dir 2>/dev/null || true)" if [ -n "$_gcd" ]; then case "$_gcd" in /*) ;; *) _gcd="$ROOT/$_gcd" ;; esac _m="$(cd "$_gcd/.." 2>/dev/null && pwd || true)" [ -n "$_m" ] && [ -d "$_m/patch_v2" ] && MAIN="$_m" fi ensure_ui_a() { local dst="$ROOT/patch_v2/sdk/meow_ui.a" got if [ -f "$dst" ]; then got="$(md5sum "$dst" | cut -d' ' -f1)" echo " meow_ui.a: 已存在 $dst ($got)" else # 候选:显式 → 主 checkout → 主 checkout 的兄弟 worktree(历史产物,最后手段) local cands=() c [ -n "${MEOW_UI_A_SRC:-}" ] && cands+=("$MEOW_UI_A_SRC") cands+=("$MAIN/patch_v2/sdk/meow_ui.a") for c in $(find "$MAIN/.tower/worktrees" -maxdepth 4 -name meow_ui.a 2>/dev/null); do cands+=("$c") done local src="" tried="" for c in "${cands[@]}"; do if [ -f "$c" ] && [ "$(stat -c%s "$c")" -gt 10240 ]; then src="$c"; break; fi tried="$tried - $c" done [ -n "$src" ] || die "缺 patch_v2/sdk/meow_ui.a(launcherd 链的 SDK 静态库,被 .gitignore 忽略)。 试过这些路径:$tried 覆盖方式:MEOW_UI_A_SRC=/path/to/meow_ui.a bash $0" cp "$src" "$dst" echo " meow_ui.a: 复制 $src → $dst" got="$(md5sum "$dst" | cut -d' ' -f1)" fi if [ "$got" != "$MEOW_UI_A_MD5" ]; then echo " !! 注意:meow_ui.a md5=$got 与 m51 批次记录的 $MEOW_UI_A_MD5 不同。" >&2 echo " 编出的 meow_launcherd md5 会随之改变(launcherd 静态链入它)。" >&2 echo " 若这是有意的 SDK 重编,请同时重跑 rebuild 并用 verify_fingerprints.sh 自证。" >&2 else echo " meow_ui.a md5 与 m51 批次记录一致($got)" fi } # ---- 兼容 HOME ---- COMPAT_HOME="${COMPAT_HOME:-${TMPDIR:-$HOME/tmp}/meow-build-home}" PROJ="$COMPAT_HOME/Project/R3ProII" rm -rf "$PROJ" mkdir -p "$PROJ" ln -sfn "$HOME/.tools" "$PROJ/.tools" # 历史脚本按 $HOME 拼 .tools ln -sfn "$ROOT/patch_v2" "$PROJ/patch_v2" # 历史脚本按 $HOME 拼源码路径时也落到当前 checkout run() { # run <组件> <工作目录> <命令...> local name="$1" dir="$2"; shift 2 echo "==> [$name] $*" ( cd "$ROOT/$dir" && HOME="$COMPAT_HOME" ZIGCC="$ZIGCC" ZIG="$ZIG" \ ZIG_GLOBAL_CACHE_DIR="$HOME/.cache/zig" "$@" ) \ || die "[$name] 构建失败(见上面的编译器输出)" } report() { local f="$ROOT/$1" [ -f "$f" ] || die "期望的产物不存在: $1" printf ' %-44s %8s B %s\n' "$1" "$(stat -c%s "$f")" "$(md5sum "$f" | cut -d' ' -f1)" } do_bootmenu=0; do_netmgrd=0; do_audiod=0; do_audio=0; do_launcherd=0 if [ $# -eq 0 ]; then do_bootmenu=1; do_netmgrd=1; do_audiod=1; do_audio=1; do_launcherd=1; fi for a in "$@"; do case "$a" in bootmenu) do_bootmenu=1 ;; netmgrd) do_netmgrd=1 ;; audiod) do_audiod=1 ;; audio) do_audio=1 ;; launcherd) do_launcherd=1 ;; *) die "未知组件: $a(bootmenu netmgrd audiod audio launcherd)" ;; esac done echo "==> 重编批次(ROOT=$ROOT)" echo " MAIN=$MAIN" echo " ZIGCC=$ZIGCC" echo " ZIG=$ZIG ($("$ZIG" version 2>/dev/null || echo '?'))" [ "$do_bootmenu" = 1 ] && { run bootmenu patch_v2/bootmenu bash build_bootmenu.sh; report patch_v2/bootmenu/meow_bootmenu; } [ "$do_netmgrd" = 1 ] && { run netmgrd patch_v2/meow_netmgrd bash build_netmgrd.sh; report patch_v2/meow_netmgrd/meow_netmgrd; } # audiod 守护:glibc-2.22 动态链接(链设备 libasound.so.2);**不链 meow_time32.c**(见 build_audiod.sh 头注)。 # meow_audio CLI:musl 静态 + meow_time32.c。 [ "$do_audiod" = 1 ] && { run audiod patch_v2/meow_audiod bash build_audiod.sh; report patch_v2/meow_audiod/meow_audiod; } [ "$do_audio" = 1 ] && { run audio patch_v2/meow_audiod bash build_audiod.sh cli; report patch_v2/meow_audiod/meow_audio; } [ "$do_launcherd" = 1 ] && { ensure_ui_a; run launcherd patch_v2/meow_launcherd bash build_launcher.sh; report patch_v2/meow_launcherd/meow_launcherd; } echo "==> 完成。产物自证:bash scripts/build/verify_fingerprints.sh"