news 2026/10/24 2:08:43

SwiftPM 如何构建签名并公证的 macOS 菜单栏应用:DS4 Control 的打包发布全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SwiftPM 如何构建签名并公证的 macOS 菜单栏应用:DS4 Control 的打包发布全流程

【免费下载链接】ds4-control

macOS menubar app for fast local DeepSeek V4.1, with 1M context.

项目地址:https://gitcode.com/gh_mirrors/ds/ds4-control
点击查看免费下载

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 驱动:

  1. 触发:推送v*.*.*语义化 tag,版本号从 tag 推导,无需手动填;
  2. 构建命令(release.yml#L20-L30):拉取子模块 → 打补丁 →make -mcpu=apple-m1编译 ds4-server →build.sh组装。注意 CPU 基线刻意钉在apple-m1而非native——避免未来新芯片的 CI 机器编出老用户 M1 Mac 无法运行的二进制(SIGILL);
  3. 签名与公证:复用共享发布 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.

项目地址:https://gitcode.com/gh_mirrors/ds/ds4-control
点击查看免费下载

相关推荐

上一篇:hallmark 指南:Ft8 Marquee Scroll 跑马灯组件——用 CSS 无限滚动打造运动感、品牌向的强律动页脚
下一篇:MochiTransformer3DModel 深度解析:Diffusers 中的 Mochi-1 视频生成 DiT 模型

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/24 2:07:42

Java学业质量分析系统开发实战与架构解析

1. 项目概述:学业质量分析系统的核心价值这个基于Java技术栈的学生学业质量分析系统,本质上是一个教育数据挖掘与可视化平台。我在实际开发中发现,传统教务系统往往只提供基础的成绩录入和查询功能,而无法从海量学生数据中提取有价…

作者头像 李华
网站建设 2026/10/24 2:00:32

Java Web学生信息管理系统实战:从部署到二次开发全解析

简介:这份资源是面向计算机专业学生与Java Web初学者的一套学生信息管理系统项目源码,对应「基于Java Web学生信息管理系统的设计与实现」主题,可用于课程设计、实训项目参考或毕业设计入门。系统以Servlet、JSP、JDBC为核心技术,…

作者头像 李华
网站建设 2026/10/24 1:57:00

2000-2024年 城市数据库(xlsx)超全面

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/24 1:53:56

Java安防SDK接入实战:JNA调用、实时预览与云台控制踩坑总结

简介:大华JAVA网络类通用SDK是面向Java开发者的网络设备二次开发工具包,专为云台摄像头、球机、半球机等设备设计。其核心能力覆盖设备发现与连接、设备状态管理、H.264/MPEG4视频流解码、实时预览与录像回放、音频编解码与双向对讲、云台上/下/左/右及缩…

作者头像 李华