通过 C ABI 嵌入
libdistribution 通过 C ABI 提供与 setup 相同的引擎,因此应用或启动器可以自己检查并应用更新。本指南链接该库并完整走一遍一次更新。
构建并链接库
Section titled “构建并链接库”在 Niobium 检出目录中,zig build 会安装:
zig-out/include/distribution.hzig-out/lib/libdistribution.a static library (macOS shown)zig-out/lib/libdistribution.dylib dynamic library即头文件、静态库(以 macOS 为例)和动态库。包含 distribution.h 并链接任一库;加上 -Dtarget=<triple> 可为其他平台构建。在 Linux 上该库不链接 libc,因此不会把你的宿主绑定到某一个 C 库。
一切都通过一个导出函数进行,它返回一张带版本的函数表:
#include "distribution.h"
const dist_api_v1 *api = NULL;if (dist_get_api(DIST_ABI_V1, &api) != DIST_OK) { /* library too old or too new for this header */}如果库相对于该头文件过旧或过新,调用会失败。每个调用都返回 DIST_OK(0)或一个负的状态值,其绝对值就是对应的退出码;例如 -4 表示信任验证失败。
dist_config_v1 config;memset(&config, 0, sizeof config);config.struct_size = sizeof config;config.repository = "https://dl.example.com/hello"; /* or a directory path */config.trust_root = root_bytes; /* contents of <N>.root.json */config.trust_root_len = root_len;config.product_id = "com.example.hello";config.channel = NULL; /* NULL means "stable" */config.scope = DIST_SCOPE_USER;config.install_dir = NULL; /* NULL: platform default */config.work_dir = NULL; /* NULL: platform cache */
dist_context *ctx = NULL;int32_t status = api->context_create(&config, &ctx);repository 可以是 URL 或目录路径;trust_root 是 <N>.root.json 的内容;channel 为 NULL 表示 stable;install_dir 和 work_dir 为 NULL 时使用平台默认位置和平台缓存。
一个上下文就是一个事务。它在第一次 check_update 或 resolve 时获取该产品的事务锁,并在 context_destroy 中释放;如果另一个事务持有该锁,你会得到 DIST_E_BUSY(-10)。
执行一次更新
Section titled “执行一次更新”dist_update_info_v1 info;memset(&info, 0, sizeof info);info.struct_size = sizeof info;
status = api->check_update(ctx, &info);if (status == DIST_OK && info.update_available) { status = api->resolve(ctx); if (status == DIST_OK) status = api->fetch(ctx); if (status == DIST_OK) status = api->stage(ctx); if (status == DIST_OK) status = api->transaction_commit(ctx);}if (status != DIST_OK && status != DIST_E_BOOTSTRAP_PENDING) { dist_buffer error = {0}; api->last_error(ctx, &error); /* {"code":"...","message":"...","exit_code":N} */}api->context_destroy(ctx);- 在 resolve 之前调用
fetch、stage和transaction_commit会返回DIST_E_USAGE(-2);如果已经是最新版本,它们什么也不做并返回DIST_OK。 - 当新版本已提交但 App Bootstrap 失败时,
transaction_commit返回DIST_E_BOOTSTRAP_PENDING(-8)。 - 通过
dist_buffer返回的缓冲区归库所有,在同一上下文的下一次调用之前保持有效。
event_subscribe(ctx, callback, user) 以不带末尾换行的 JSON 字节传递每一个事件。cancel(ctx) 可以从任意线程调用;正在运行的操作会在下一个检查点以 DIST_E_CANCELLED(-9)停止。
- 该库从不显示提权提示。只有当你的进程本身已经提权时,整机范围才可用;否则调用返回
DIST_E_PERMISSION(-7)。 - 在 Linux 上它从
/proc/self/environ读取环境变量,因此你的进程在启动之后设置的变量不会被看到。
以这种方式安装一个产品的完整程序是 C 冒烟测试 tests/c-smoke/main.c。逐个函数的语义见 C ABI 参考。