环境要求
| 项目 | 要求 |
|---|---|
| Rust | 1.85+(workspace rust-version) |
| Linux 依赖 | alsa-lib dbus fontconfig freetype2 hicolor-icon-theme libxkbcommon libxcb |
| macOS | Apple Silicon,Xcode Command Line Tools |
| Windows | x64,MSVC 工具链 |
构建与运行
仓库自带带内存护栏的脚本(这台开发机 15GB 内存,GPUI 编译较重,曾出现过 OOM):
git clone https://github.com/sodahub-org/sodam cd sodam scripts/check.sh # cargo check + fmt --check + clippy -D warnings + test scripts/build.sh # 构建(默认 debug,--release 出正式包) scripts/run.sh # 启动 GUI(带 MemoryMax 护栏,编译时不要跑)
资源护栏:编译时不跑 GUI、跑 GUI 时不编译;卡顿时先看
journalctl -k | grep -iE "drm|flip_done|oom"。
提交前必须跑 scripts/check.sh;UI 改动必须用 scripts/run.sh 真机验证,不能只过 cargo check。
目录结构
| 路径 | 职责 |
|---|---|
crates/sodam-core/ | 领域层:配置、会话、队列、音乐库、播放引擎(不依赖 GPUI) |
crates/sodam/ | GPUI 应用:入口、Root 状态、动作、托盘、ui/、views/ |
packaging/arch/ | PKGBUILD、desktop 文件、mkrepo.sh(生成 pacman 源) |
packaging/homebrew/ | Homebrew Cask |
website/ | 本官网(静态页面,CI 部署到 GitHub Pages) |
docs/ | ARCHITECTURE / ROADMAP / UI-SPEC |
scripts/ | check / build / run(带内存护栏) |
架构要点
- 领域层不依赖 GPUI:
sodam-core是纯 Rust,可单独测试。 - 渲染线程不阻塞:libresoda 的 HTTP / 下载是阻塞操作,必须放在
cx.background_spawn或专用线程,结果回 UI 后cx.notify()。 - 状态只有一处:播放、队列、导航、设置由
Root或 core 模型持有;UI 只读状态、生成元素、派发动作。 - 音频线程独立:rodio 的
OutputStream是!Send,所以音频对象全留在sodam-audio线程,UI 通过命令通道操作、通过PlaybackSnapshot读状态。 - 错误不 panic:网络/配置错误写进
Root::status或页面提示;只有启动期不可恢复错误才允许 panic。 - 播放跟随系统默认设备:音频线程每 2 秒探测默认输出设备 ID,变化时重建输出并从原位置续播。
更详细的线程模型见仓库 docs/ARCHITECTURE.md。
开发约定
- 接口能力先在 libresoda 打通:SodaM 只做调用与展示,不绕过 libresoda 直接请求汽水接口。
- 凭据不入库、不入日志:Cookie、签名 Token、抓包签名头、真实设备指纹禁止提交或打印。
- 界面文案走 i18n:新增用户可见文案用
root.tr/root.localized,中文原文作为稳定 key,同步英文词典。 - 不引入个人数据:不提交真实 Cookie、签名头、本机路径或账号数据。
- UI 改动必须真机验证,提交前跑
scripts/check.sh。
提交与评审
- 从
main切分支:feat/…/fix/…/docs/…。 - commit message 用中文祈使句 + 类型前缀:
fix(audio): …、feat(ui): …。 - 本地跑
scripts/check.sh,UI 改动用scripts/run.sh真机确认。 - 开 PR,说明「问题 / 原因 / 修复 / 验证」四段;CI 会跑四平台(Linux x86_64 & aarch64、macOS arm64、Windows x64)。
- Review 通过后 squash 合并。
发布流程
- 改版本号:
Cargo.toml的[workspace.package] version(Cargo.lock同步)、packaging/arch/PKGBUILD、README 里的版本示例。 - 先由发版工作流生成产物,按
SHA256SUMS更新 Homebrew Cask 并提交; - 在包含正式 Cask 校验和的提交上打附注 tag,tag message 就是发布说明:
git tag -a v0.3.5 -F changelog.txt git push origin main git push origin v0.3.5
CI 会构建四平台产物、创建 GitHub Release,然后自动重建 pacman 源并部署本官网。
- 用
packaging/homebrew/sync-tap.sh把同一 Cask 同步到 homebrew-tap 仓库。 - pacman 源需要补跑时:
gh workflow run pages.yml -f tag=v0.3.5。
维护者与贡献者
欢迎提 Issue / PR:先读 CONTRIBUTING.md, 提问题请用 issue 模板; 涉及界面改动请附真机截图。