【免费下载链接】ds4-control
macOS menubar app for fast local DeepSeek V4.1, with 1M context.
DS4 Control 是一款运行在 macOS 菜单栏上的本地 DeepSeek V4 控制中心,它通过 SwiftPM 构建单一 Swift 可执行文件,再由 build.sh 完成.app组装、代码签名,最后经 CI 完成 Apple 公证并产出 Gatekeeper 干净的.dmg。本文完整拆解这条"从源码到可分发应用"的打包发布链路,帮助新手理解 SwiftPM 项目在 macOS 上落地签名与公证的每一步。
为什么选 SwiftPM:一个文件定义整个构建
很多 macOS 应用用 Xcode 工程,但 DS4 Control 选择纯 SwiftPM:一个 Package.swift 就声明了平台、依赖和 target。
swift-tools-version: 6.3+.macOS(.v15)锁定语言与系统基线;- 依赖的 MarkdownView 是打了两个补丁的 fork,用精确 revision 固定版本,保证签名构建可复现;
executableTarget直接指向 Sources/DS4Control/,并声明资源与IOKit、IOReport等私有/系统库链接。
好处是零 Xcode 工程文件、swift build -c release即可出二进制,天然适合脚本化与 CI。
一键打包:build.sh 的六道工序
执行bash build.sh后,build.sh 按顺序完成以下工作,每道工序都有明确的"为什么":
1️⃣ 释放构建并取回二进制
swift build -c release产出DS4Control可执行文件,随后创建DS4 Control.app/Contents/MacOS与Resources骨架,拷入 Info.plist(其中LSUIElement让应用只驻留菜单栏、不占 Dock 图标),并用PlistBuddy写入版本号。
2️⃣ 拦截编译,修正资源 Bundle 定位(最隐蔽的一坑)
SwiftPM 为每个依赖生成resource_bundle_accessor.swift,默认从Bundle.main.bundleURL(即.app根目录)找.bundle——而 macOS 禁止在根目录放未密封内容,上架后会直接崩溃。build.sh 的解法很巧妙:用SWIFT_EXEC拦截编译器,在每次编译前把路径重写为Bundle.main.resourceURL(即Contents/Resources,可被签名密封、可被公证)(详见 build.sh#L11-L42)。
3️⃣ 内嵌 Bundle 补 Info.plist + 回归保护
把所有*.bundle(含嵌套的)拷进Contents/Resources;对缺 Info.plist 的数据型 bundle 现场合成一份,否则codesign会报 "bundle format unrecognized"。脚本还内置一道回归检查:Highlightr_Highlightr.bundle缺失即中止构建——这是 v1.0.0 真实崩溃过的点(见 build.sh#L60-L95)。
4️⃣ 图标生成
用sips从Resources/icon.png缩放出 16–512px 全套尺寸,再由iconutil合成AppIcon.icns,全程无需人工维护 iconset。
5️⃣ 内嵌 ds4 推理引擎产物
把ds4-server(约 1 MB)、Metal 着色器源与download_model.sh拷入Resources/ds4(见 build.sh#L109-L122)。几百 GB 的模型权重不打包,运行时下载到 Application Support——这是"自包含却轻量"的关键取舍。ds4 本体来自 external/ds4 子模块,发布前由 scripts/apply-ds4-patches.sh 打上补丁。
6️⃣ 代码签名:从内到外的三道 codesign
签名顺序由内到外:先签嵌套的ds4-server,再签主二进制,最后签整个.app,全部带--options runtime(启用 Hardened Runtime,公证的前提)。身份自动探测:security find-identity找Apple Development证书;找不到就回退ad-hoc 签名——本地能跑,但不可分发(见 build.sh#L124-L142)。
CI 自动发布:Developer ID 签名 + Apple 公证
真正的分发链路由 .github/workflows/release.yml 驱动:
- 触发:推送
v*.*.*语义化 tag,版本号从 tag 推导,无需手动填; - 构建命令(release.yml#L20-L30):拉取子模块 → 打补丁 →
make -mcpu=apple-m1编译 ds4-server →build.sh组装。注意 CPU 基线刻意钉在apple-m1而非native——避免未来新芯片的 CI 机器编出老用户 M1 Mac 无法运行的二进制(SIGILL); - 签名与公证:复用共享发布 workflow,用Developer ID证书签名、提交 Apple 公证、打包 Gatekeeper 干净的
DS4-Control.dmg;team-id走仓库变量、证书走 secrets,不出现在源码里。
日常质量由 .github/workflows/ci.yml 兜底:format lint、release 构建(警告即错误)、swift test,最后做一次bundle 冒烟测试——build.sh跑通后断言可执行文件与内嵌的ds4-server都存在。
关键文件速查
| 环节 | 文件 |
|---|---|
| 依赖与平台声明 | Package.swift |
| 一键打包 + 签名脚本 | build.sh |
| 应用元信息(Bundle ID、LSUIElement) | Info.plist |
| 发布流水线(签名/公证/dmg) | .github/workflows/release.yml |
| CI 构建与冒烟测试 | .github/workflows/ci.yml |
| 菜单栏入口与激活策略 | Sources/DS4Control/DS4ControlApp.swift |
| ds4 推理引擎子模块 | external/ds4 |
| 版本变更记录 | CHANGELOG.md |
结语
DS4 Control 展示了 SwiftPM 项目发布 macOS 应用的完整范式:SwiftPM 管依赖与编译,脚本管 Bundle 组装,codesign 从内到外,CI 管公证与分发。其中最有参考价值的三个细节——SWIFT_EXEC拦截修正Bundle.module路径、CPU 基线钉死防 SIGILL、bundle 缺失即中止构建的回归保护——正是区分"能跑"和"能上架"的分水岭。
【免费下载链接】ds4-control
macOS menubar app for fast local DeepSeek V4.1, with 1M context.
相关推荐
ILSpy macOS 发布全流程:CI 无签名构建、离线签名公证与 DMG 打包实战
ILSpy macOS 发布全流程:CI 无签名构建、离线签名公证与 DMG 打包实战 本篇指南以 ILSpy 仓库中 BuildTools/packaging
逆向工程开发工具OfficeDex 构建发布全流程指南:macOS 打包签名与 Apple 公证一站式教程
OfficeDex 构建发布全流程指南:macOS 打包签名与 Apple 公证一站式教程 OfficeDex 是首个 AI Native VibeOffici
LeRobot 训练可视化:跟踪指标、观察状态、复盘评估视频
LeRobot 训练可视化:跟踪指标、观察状态、复盘评估视频 LeRobot 训练可视化覆盖三类场景:用 WandB 做训练指标跟踪,用 Rerun 实时查看传
人工智能具身智能机器人深度学习强化学习数据集计算机视觉
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考