app.json 二进制依赖 depends:启动前检查(launcher)+ 安装提示(nyai)

需求(用户定案):App 复杂功能若依赖现成 Linux 二进制(板载 /usr/bin 或卡上
MeowOS/opt/bin)能效更好,声明后系统启动 App 前检查依赖是否存在。

- depends 行式声明:depends=curl,jq:optional,ffmpeg:required(无标注默认
  required;也接受 :opt/:req;未知修饰符按 required 处理并 WARN;空项/超量丢弃)
- launch_app_chain 冷启动时按序查 /usr/bin/<name> 与 <卡>/MeowOS/opt/bin/<name>
  (X_OK,两类命中即满足);缺 required → 不启动(toast「缺依赖: <name>」+ 日志,
  沿用 CANNOT START 风格);optional 缺失 → 仅 WARN 放行;只在启动时查,不做周期复查
- nyai install 对包内 app.json depends 同查并提示(不阻断安装,缺 required 标注
  「安装后启动将失败」)
- 新增 meow_dep.c(独立 TU,解析/检查/块原因),宿主测试 test_depends.c
  解析矩阵 12 用例 + 假根检查路径 12 用例全 PASS;launcher/nyai mipsel 交叉
  -Wall -Wextra 0 warning;launcher 现有宿主测试回归全过
- 文档:APPS.md §2.1 字段表 + docs/MEOWOS_SPEC_REF.md §5.5 同步;hello app.json
  加 depends:curl:optional 示例

launcher md5 899ac22c10f596909d7f35ea685744de(fw_content.conf 已更新;/usr/bin
只读,留给主会话打包固件)
This commit is contained in:
MeowOS committed 2026-09-01 18:28:07 +08:00
1 parent 9e25db77cc
commit ed2ae10320
14 files changed
+416 -12

No files matched your search

+15 -7
View File
@@ -13,6 +13,16 @@
int menu_opened_blank = 0;
/* launch_app/launch_activity 返回 -1 时的 toast:缺二进制依赖(app.json depends)→ 「缺依赖: <name>」;
* 其余启动失败沿用「CANNOT START: <name>」。原因由 meow_dep.c 的 meow_dep_block_reason() 提供。 */
static void launch_fail_toast(char *toast, size_t n, const char *name)
{
const char *bd = meow_dep_block_reason();
if (bd && bd[0]) snprintf(toast, n, "缺依赖: %s", bd);
else snprintf(toast, n, "CANNOT START: %s", name);
}
/* ---- config (MeowAPPs/meow.conf): pure black background by default ---- */
uint32_t menu_bg = 0x000000;
@@ -904,7 +914,7 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
ret = launch_app(&apps[idx]);
}
if (ret != 0) {
snprintf(toast, sizeof toast, "CANNOT START: %s", apps[idx].name);
launch_fail_toast(toast, sizeof toast, apps[idx].name);
toast_ms = TOAST_MS;
}
menu_after_app_exit(ret == 0);
@@ -938,7 +948,7 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
last_input_ms = now_ms(); /* M2.17:回主界面即视为输入,重置自动息屏计时 */
dirty = 1; /* app wrote buffer0 during its run -> redraw menu */
if (ret != 0) {
snprintf(toast, sizeof toast, "CANNOT START: %s", apps[0].name);
launch_fail_toast(toast, sizeof toast, apps[0].name);
toast_ms = TOAST_MS;
}
} else {
@@ -1297,8 +1307,7 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
last_input_ms = now_ms();
dirty = 1;
if (ret != 0) {
snprintf(toast, sizeof toast, "CANNOT START: %s",
apps[click.app_idx].name);
launch_fail_toast(toast, sizeof toast, apps[click.app_idx].name);
toast_ms = TOAST_MS;
}
} else if (click.status == NOTIF_CLICK_STATUS_NOROUTE) {
@@ -1392,8 +1401,7 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
last_input_ms = now_ms();
dirty = 1;
if (ret != 0) {
snprintf(toast, sizeof toast, "CANNOT START: %s",
apps[click.app_idx].name);
launch_fail_toast(toast, sizeof toast, apps[click.app_idx].name);
toast_ms = TOAST_MS;
}
} else if (click.status == NOTIF_CLICK_STATUS_NOROUTE) {
@@ -1497,7 +1505,7 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
last_input_ms = now_ms(); /* M2.17:回主界面即视为输入,重置自动息屏计时 */
dirty = 1; /* app wrote buffer0 -> redraw menu */
if (ret != 0) {
snprintf(toast, sizeof toast, "CANNOT START: %s", apps[idx].name);
launch_fail_toast(toast, sizeof toast, apps[idx].name);
toast_ms = TOAST_MS;
}
}