Appearance
构建与部署 — 概念
部署管线总览
从源代码到用户可访问的网站,pokeemerald-wasm 经历以下阶段:
Makefile 构建目标
make wasm — 完整 WASM 构建
这是核心构建目标,执行以下步骤:
关键编译标志:
| 标志 | 含义 |
|---|---|
--target=wasm32-unknown-unknown | 编译目标为 WebAssembly 32 位 |
-DMODERN=1 | 启用 modern 模式(使用现代 C 编译器) |
-DWASM=1 | 启用 WASM 条件编译守卫 |
-I include/wasm | 优先搜索 WASM 兼容垫片头文件 |
-O2 | 二级优化 |
--no-entry | WASM 模块无标准 main() 入口 |
--allow-undefined | 允许未定义符号(GBA BIOS 调用等) |
--initial-memory=268435456 | 初始化 256MB 线性内存 |
--export=AgbMain | 导出游戏入口函数 |
--export=WasmRunFrame | 导出帧执行函数 |
--export-all | 导出所有全局符号(用于调试和自动化) |
make serve-wasm — 本地开发服务器
编译 WASM 后启动 Node.js 开发服务器:
make wrangler-site — 部署打包
构建 WASM 并打包 Cloudflare Workers 所需的静态资源:
make clean-wasm — 清理构建产物
删除 build/wasm/ 目录中的所有编译中间文件和最终产物。
原生构建目标(wasm2c 管线)
上游新增(2026-07 同步)
除浏览器前端外,上游新增三条原生构建目标。它们都先把 WASM 用 WABT 的 wasm2c 转回 C,再链接各自的宿主程序,复用同一份游戏与渲染核心(src/wasm_display.c 的 RGBA 输出)。
| 目标 | 产物 | 说明 |
|---|---|---|
make native-raylib | build/native/pokeemerald-native | 桌面 Raylib 前端,native-raylib 用同一 WASM ABI,存档写入 *.sav |
make native-bench | build/native/pokeemerald-bench | 无头 FPS + 正确性基准测试,不开窗口;tools/native/run_bench.sh 跑两遍并对照 bench_golden.json 的 FNV 哈希,任一不匹配则分数为 0 |
make native-kindle | build/native/pokeemerald-kindle | Kindle Scribe Linux 帧缓冲前端:灰度帧写 /dev/fb0,读 /dev/input/event*,经 HWTCON/MXCFB 或 eips 刷新电子墨水屏。可用 KINDLE_CC/KINDLE_CFLAGS 交叉编译(如 zig cc) |
make clean-native | — | 清理 build/native/ |
关键点:
- wasm2c 把同一份 WASM 翻译成可由普通 C 编译器链接的代码,于是「在浏览器里跑」和「在桌面 / Kindle 上跑」共享同一个游戏核心,无需维护第二份移植。
native_engine.h定义了与浏览器相同的 240×160 RGBA 显示约定(NATIVE_DISPLAY_WIDTH/HEIGHT、NATIVE_DISPLAY_BYTES)和按键位掩码,宿主只负责把 RGBA 搬到屏幕——这与app.js的WasmRenderFrame()+putImageData()模式完全一致。
本地开发服务器
web/server.mjs 是一个极简的静态文件服务器:
特点:
- 基于 Node.js 原生
http模块,无第三方依赖 - 自动路径安全检查(防止目录遍历攻击)
- 所有响应设置
Cache-Control: no-store(开发时不缓存)
Cloudflare Workers 部署
wrangler.toml 配置
toml
name = "pokeemerald-wasm"
account_id = "..."
compatibility_date = "2026-05-29"
workers_dev = false # 不使用 *.workers.dev 子域
preview_urls = false # 禁用预览 URL
[build]
command = "make wrangler-site" # 构建命令
watch_dir = ["web", "src", "include", ...] # 监听变更的目录
[assets]
directory = "./dist/cloudflare" # 静态资源目录
html_handling = "auto-trailing-slash"
not_found_handling = "none"
[[routes]]
pattern = "pokeemerald.com" # 自定义域名
custom_domain = true关键配置项:
| 配置 | 值 | 说明 |
|---|---|---|
workers_dev | false | 禁用 workers.dev 子域,仅通过自定义域名访问 |
build.command | make wrangler-site | 部署前自动执行构建 |
assets.directory | ./dist/cloudflare | 静态资源来源目录 |
routes | pokeemerald.com | 绑定自定义域名 |
打包脚本:build_wrangler_site.mjs
打包的 4 个文件:
| 源文件 | 目标路径 | 说明 |
|---|---|---|
web/index.html | dist/cloudflare/index.html | 主页面(Canvas + 控件) |
web/app.js | dist/cloudflare/web/app.js | 运行时(输入/存档/帧调度;渲染在 WASM 内完成) |
web/style.css | dist/cloudflare/web/style.css | UI 样式 |
build/wasm/pokeemerald.wasm | dist/cloudflare/build/wasm/pokeemerald.wasm | WASM 模块 |
相关概念
- Cloudflare Workers — 边缘计算平台,托管静态资源
- WASM 编译管线 — Clang 编译和 wasm-ld 链接
- 源码兼容与适配 —
#if WASM条件编译 - 项目架构概览 — 整体项目结构