【免费下载链接】Husk
Run Android on your iPhone. Natively or Emulated.
Husk 是一款"让 iPhone 直接运行安卓游戏和 App"的开源项目,而它最容易被忽略的亮点,恰恰藏在 LICENSE 和 docs/01-licensing.md 里——一套教科书级的开源许可(Open Source License)选型方案。Husk 整体采用 GPLv2 许可,同时项目里还"撞"上了 Apache-2.0、AGPL-3.0、MPL-2.0、MIT 等多种许可。这篇文章带你弄懂:GPLv2 为什么是"没有选择的选择"、为什么 UTM 的 Apache-2.0 代码碰都不能碰,以及法律条款如何一步步决定了这个项目的分发方式。
先认识一下 Husk:一个"双引擎"安卓运行器
Husk 的玩法很简单:把一个 APK 拖进 App,点一下,就能在 iPhone 上全屏运行。它内部有两条完全不同的技术路线(Library 界面的两个"分区"):
- 翻译层(Translation Layer):游戏自己的 64 位 Android 代码直接在 iPhone 处理器上跑,Husk 在旁边"扮演"安卓系统——C 库、Java 调用、OpenGL ES、Vulkan、声音、触摸全部由它接管。核心实现在 src/translation-layer/;
- 完整模拟:在 QEMU 虚拟机里启动整套 LineageOS 安卓系统,用于翻译层还跑不动的 App。
正是"模拟"路线里链接的QEMU,决定了 Husk 整个许可策略的走向。
为什么是 GPL-2.0-or-later?因为 QEMU 没有给退路
这是本文的核心问题之一:开源项目的许可不是想选什么就选什么,而是被依赖项"绑架"的。
原因有两层,且互为独立:
- QEMU 整体是 GPLv2。Husk 把 QEMU 编译成
libqemu-aarch64-softmmu.dylib直接链进自己的进程,并随 IPA 一起分发——这在法律上叫"结合作品(combined work)",整包必须按 GPLv2 对待。Husk 自己的代码选GPL-2.0-or-later,正好与 QEMU 兼容,同时又为将来升级到 GPLv3 留了口子; - JIT 内存分配器代码来自 shadPS4 的 AetherPS4-iOS,原文件头就写着
GPL-2.0-or-later(见 src/ios-jit/husk-ios-jit.c),所以就算没有 QEMU,它也是 GPL 的。
项目里每一个 Husk 自研文件都带 SPDX 许可头(如SPDX-License-Identifier: GPL-2.0-or-later),连给 QEMU 打的补丁 patches/husk-qemu-ios-jit.patch 也标注为 "GPL-2.0-or-later, same as the file it patches"——许可跟着被修改文件的许可走,这是非常规范的工程实践。
真正的陷阱:UTM 的 Apache-2.0 应用代码"只能抄想法,不能抄代码"
Husk 基于 UTM 的 QEMU 构建方案起步,而UTM 的 App 代码是 Apache-2.0。这里就出现了标题里的"碰撞":
⚠️Apache-2.0 与 GPLv2 不兼容(它只与 GPLv3 兼容,但 QEMU 整体是 GPLv2,救不了场)。
所以 Husk 给"能从 UTM 拿什么"画了一张清晰的清单:
| 来源 | 许可 | 能不能用? |
|---|---|---|
| UTM 构建用的 QEMU 代码包 | GPL-2.0(它本身就是 QEMU) | ✅ 可以 |
UTM 的build_dependencies.sh构建脚本 | ISC | ✅ 宽松许可,可以 |
| UTM 的 Swift/ObjC 应用代码、CocoaSpice、UI | Apache-2.0 | ❌禁止复制 |
注意一个精妙细节:patches/目录里直接 vendor 了 UTM 的补丁文件(patches/README.md),因为这些补丁改的是 QEMU、pixman、libslirp,它们的许可归属是各自上游项目(如 GPL-2.0),而不是 UTM 的 Apache-2.0。许可看"改的是谁的文件",而不是"补丁从哪抄来"——这个区分很多开发者都会搞错。
AGPL-3.0 的 StikDebug 为什么"无罪"?
iOS 上的 JIT(即时编译)权限必须由调试器授予,所以很多用户需要另装一个调试器 AppStikDebug,它是AGPL-3.0许可——听起来很吓人(AGPL 连网络服务都管)。
但 Husk 的解法是进程级隔离:
- StikDebug 是独立应用,通过 gdb-remote 协议附加到 Husk;
- 两者之间没有链接、没有共享地址空间,跨边界传递的只是一条"线上协议(wire protocol)",而协议本身不是可版权的对象;
- 用户从 StikDebug 自己的渠道安装,Husk 只做文档说明和链接,绝不打包捆绑。
结论:只要不构成"链接/派生作品",AGPL 就管不到你。这是处理强 Copyleft 依赖的经典思路。
内置 StikJIT:MPL-2.0 与 MIT 如何安全入包
从 iOS 26 开始,Husk 可以用内置 StikJIT(docs/06-built-in-jit.md)自己开启 JIT,这时确实要打包第三方代码了,许可盘点如下:
| 组件 | 许可 | 状态 |
|---|---|---|
| StikJIT 1.9.0 XCFramework | MPL-2.0 | 未修改,原样嵌入 |
| idevice 库 | MIT | 已链接 |
| Rust 依赖(src/rppairing-ios/Cargo.lock 锁定版本) | MIT / Apache-2.0 / BSD-3 / ISC | 静态链接 |
关键在于MPL-2.0 是"文件级"的 Copyleft:它只要求 MPL 文件本身的修改开源,且 MPL-2.0 第 3.3 条明确与 GPL 兼容——所以它放进 GPL 主工程完全没问题。许可文本也随包分发在 src/app/Husk/Resources/legal/,包括LICENSE-StikJIT-MPL-2.0.txt、LICENSE-idevice-MIT.txt等。
一次漂亮的工程+法律双赢:删掉"无许可"二进制
Husk 曾依赖一个叫BreakpointJIT.framework的第三方二进制,但它分发物里没有任何许可文件。无许可(unlicensed)的二进制,GPL 项目是不能依赖的——默认版权保留,你什么权利都没有。
最终解决方案堪称典范:反汇编后发现这个 framework总共只有 11 条指令(几对brk断点指令,语义完全由 StikDebug 的公开协议文档规定)。于是 Husk 自己在 src/ios-jit/husk-brk.S 里用汇编重新实现,"复刻"的只是接口约定而非任何人的创造性表达。
顺带的工程收益更大:删掉 framework 后,dlopen间接层和 AMFI 启动失败(带 entitlements 的内嵌 framework 在侧载构建上会被拒载)也一并消失了。法律风险归零,代码还更干净——这就是许可思维反哺工程设计的例子。
分发方式:许可条款直接决定了"上不了 App Store"
许可不只是文件头,它直接改写了产品分发路线:
- 📦公开、完整、可构建的源码仓库——这才是满足 GPLv2 第 3 条(分发二进制须附对应源码)的方式;
- 📱侧载分发:通过 AltStore / SideStore / TrollStore 安装 IPA,随包提供完整源码;
- 🚫放弃 App Store,且有两个独立的理由:GPLv2 条款与 App Store 分发限制冲突(经典的 VLC 问题),以及 Husk 必须依赖
get-task-allow+ 运行时附加调试器才能开 JIT,审查根本不会放行。
还有一个"留白但没忘"的问题(见 docs/01-licensing.md 末尾):模拟模式启动的Linux 内核是 GPLv2,未来若要随包分发内核二进制,就必须连同其源码一起提供;而Google Play Services 被明确禁止捆绑——这同样被定性为许可层面的禁令,不只是"太复杂"。
给开发者的三条启示 📌
- 先定许可,再写代码:Husk 在"写下大量自研代码之前"就把许可问题裁定完毕,避免返工;
- 依赖许可做"资产盘点":每一行第三方代码都标注许可、存放位置和兼容结论(本项目在 docs/01-licensing.md 中全部"对照真实源码树核验过,不凭记忆");
- 隔离优于侥幸:AGPL 用进程边界隔离、Apache-2.0 用"只借想法不抄代码"、MPL 靠文件级条款入包——同一项目里展示了三种不同的兼容性解法。
延伸阅读:项目整体架构见 docs/00-architecture.md,翻译层原理见 docs/04-translation-layer.md,QEMU 相关补丁说明见 patches/README.md。
【免费下载链接】Husk
Run Android on your iPhone. Natively or Emulated.
相关推荐
Kata Containers 开源许可策略解析:Apache 2.0 双轨授权与 SPDX 标识的工程落地
Kata Containers 开源许可策略解析:Apache 2.0 双轨授权与 SPDX 标识的工程落地 本篇技术指南以 docs/Licensing st
云原生容器运行时终极指南:Bend语言Apache 2.0许可证合规详解与知识产权保护策略
终极指南:Bend语言Apache 2.0许可证合规详解与知识产权保护策略 Bend作为一种大规模并行的高级编程语言(A massively parallel,
编程语言编译器语言运行时高性能计算免Root去预装完整攻略:用Universal Android Debloater快速卸载安卓预装应用
免Root去预装完整攻略:用Universal Android Debloater快速卸载安卓预装应用 刚拆封的新手机里躺着一堆你大概率永远不会打开的应用,电量
桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考