恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Madeira 实战:在 iOS 上通过 FEX-Emu 与 Wine 运行 Windows 游戏
首页
资讯中心
/
Madeira 实战:在 iOS 上通过 FEX-Emu 与 Wine 运行 Windows 游戏
Madeira 实战:在 iOS 上通过 FEX-Emu 与 Wine 运行 Windows 游戏
发布时间:2026/10/1 1:17:23
1. 项目缘起为什么我要折腾 Madeira第一次看到“Madeira”这个词很多人会以为是葡萄牙那个产葡萄酒的海岛。但在我们这行尤其是最近这段时间Madeira 指的是一套围绕FEX-Emu、Wine、DXMT构建的跨架构兼容方案目标很明确让 x86-64 的 Windows 应用和游戏在 ARM 设备上跑起来尤其是 iOS 设备。你没看错就是 iPhone 和 iPad。这个项目的核心逻辑其实不复杂。Apple Silicon 的 Mac 早就通过 Rosetta 2 实现了 x86-64 到 ARM 的指令翻译但 iOS 设备上一直没有官方的同类方案。Madeira 做的事情就是把这套思路搬到 iOS 上用FEX-Emu做 CPU 指令翻译把 x86-64 指令实时转成 ARM64 指令用Wine提供 Windows API 兼容层再用DXMT把 DirectX 调用翻译成 Metal让游戏能调用 iOS 设备的 GPU。这套组合拳打下来理论上你可以在 iPhone 上跑 Windows 版的《植物大战僵尸》或者一些老款独立游戏。听起来很酷但实际操作中坑非常多。我前后折腾了大概三周从编译 FEX-Emu 到配置 Wine 前缀再到处理 DXMT 的着色器缓存中间踩过的坑足够写一本小册子。这篇文章就是把这些经验整理出来给同样想尝试的人一个参考。适合谁看如果你是对 iOS 底层技术感兴趣的开发者或者想在移动设备上跑 Windows 应用的技术爱好者这篇文章会很有用。如果你只是想找个现成工具点点按钮就能用那 Madeira 目前还不适合你它的成熟度大概相当于 2010 年的 Wine——能用但需要大量手动配置。2. 核心组件拆解FEX-Emu、Wine 和 DXMT 各自扮演什么角色2.1 FEX-Emux86-64 到 ARM64 的实时翻译引擎FEX-Emu 是整个方案的地基。它的工作原理是JIT 编译当 x86-64 程序执行时FEX-Emu 把每一条 x86-64 指令翻译成对应的 ARM64 指令然后交给 CPU 执行。这个过程是动态的翻译结果会被缓存起来所以第二次执行同一段代码时速度会快很多。为什么不用静态翻译因为 Windows 程序大量使用动态链接库和运行时生成的代码静态翻译根本处理不了。JIT 虽然启动慢一点但兼容性好得多。FEX-Emu 还有一个Thunking 机制允许 x86-64 代码直接调用 ARM64 的原生库比如图形驱动和系统调用这样就不需要把整个图形栈都翻译一遍性能损耗小很多。在实际配置中FEX-Emu 的RootFS需要特别注意。RootFS 是一个包含 x86-64 版 Linux 基础库的根文件系统Wine 和 Windows 程序都跑在这个环境里。我建议用 Ubuntu 20.04 的 x86-64 RootFS因为它的库版本比较老兼容性反而更好。太新的库有时候会因为 glibc 版本问题导致 Wine 启动失败。注意FEX-Emu 的 RootFS 不要和宿主系统的库混用。我一开始图省事直接把宿主机的 /usr/lib 挂载进去结果 Wine 加载器直接崩溃。后来老老实实下载了一个完整的 Ubuntu 20.04 x86-64 RootFS问题才解决。2.2 WineWindows API 的兼容层Wine 的作用是把 Windows 的系统调用翻译成 POSIX 调用。比如 Windows 程序调用CreateFileWine 会把它转换成 Linux 的open系统调用。在 Madeira 方案里Wine 跑在 FEX-Emu 的 RootFS 里面所以它本身也是 x86-64 版本的 Wine由 FEX-Emu 负责翻译成 ARM64 指令。这里有个关键点Wine 的版本选择。我试过 Wine 8.x 和 Wine 9.x最后发现 Wine 8.0.2 最稳定。新版本虽然支持更多 API但在 FEX-Emu 环境下容易出现线程同步问题表现为程序随机卡死。Wine 8.0.2 的代码路径更简单翻译后的指令数更少反而更可靠。Wine 的配置核心是WINEPREFIX。每个 Windows 程序最好有独立的 prefix避免 DLL 冲突。创建 prefix 的命令是WINEPREFIX~/.wine-madeira WINEARCHwin64 wineboot -u这个命令会初始化一个 64 位的 Wine 环境。注意WINEARCHwin64必须指定否则默认是 win32很多现代游戏跑不起来。2.3 DXMTDirectX 到 Metal 的翻译层DXMT 是让游戏能跑起来的关键。iOS 设备只有 Metal API没有 DirectX所以必须把 D3D 调用翻译成 Metal。DXMT 支持 D3D11 和部分 D3D12通过SPIR-V中间格式做转换先把 D3D 着色器编译成 DXBC再转成 SPIR-V最后用 Metal 的着色器编译器生成 Metal 二进制。这个过程听起来很绕但实际效果还不错。我测试了《空洞骑士》和《星露谷物语》都能稳定在 30-60 帧。不过 DXMT 对着色器缓存很敏感。第一次运行游戏时每个新着色器都要现场编译会卡顿几秒。编译完成后缓存到磁盘第二次就流畅了。所以建议第一次运行时耐心一点让缓存充分生成。DXMT 的配置主要在dxmt.conf文件里。关键参数是shader_cache_path和max_shader_cache_size。我一般把缓存路径设在应用沙盒的 Documents 目录下大小限制设 512MB基本够用。3. 实操环境搭建从零开始配置 Madeira3.1 准备工作设备、系统版本和工具链首先说设备要求。我用的是一台 iPad Pro M1系统版本 iPadOS 17.4。为什么强调系统版本因为 Madeira 依赖JIT 权限而 iOS 从 14 开始就严格限制 JIT。你需要开启开发者模式并且用TrollStore或者类似工具给应用授予dynamic-codesigning权限。没有这个权限FEX-Emu 的 JIT 根本跑不起来。具体步骤先在设置里开启开发者模式设置 → 隐私与安全性 → 开发者模式然后重启设备。接着用 AltStore 或者 Sideloadly 安装一个带get-task-allow权限的应用。这个权限允许调试器附加也是 JIT 的前提。最后用Jitterbug或者StikDebug这类工具在应用启动时附加调试器激活 JIT。注意iOS 26.3.1 之后开发者模式的入口位置变了现在在“隐私与安全性”最下面。如果找不到先连接 Xcode 一次系统会自动提示开启。工具链方面你需要一台 Mac 用来编译和签名。Xcode 版本建议 15.4 以上因为要支持最新的 iOS SDK。另外需要安装CMake、Ninja和LLVMFEX-Emu 和 DXMT 都用 CMake 构建。3.2 编译 FEX-Emu参数选择和常见错误FEX-Emu 的编译不算复杂但参数选择很关键。我用的配置是cmake -G Ninja \ -DCMAKE_BUILD_TYPERelease \ -DENABLE_ASSERTIONSOFF \ -DENABLE_LTOON \ -DCMAKE_TOOLCHAIN_FILEios.toolchain.cmake \ -DPLATFORMOS64 \ -DARCHSarm64 \ ..ENABLE_LTOON是必须的链接时优化能减少 20% 左右的指令数对性能提升明显。ENABLE_ASSERTIONSOFF也要关掉否则运行时会有大量断言检查拖慢速度。编译过程中最容易遇到的错误是Thunk 库缺失。FEX-Emu 需要链接 iOS 的libSystem和libobjc但默认的 CMake 配置可能找不到这些库。解决办法是在CMakeLists.txt里手动指定target_link_libraries(fexcore PRIVATE -framework Foundation -framework UIKit -lobjc )另一个坑是RootFS 的路径。FEX-Emu 默认从/usr/share/fex-emu/RootFS加载但 iOS 应用沙盒里没有这个路径。你需要在启动 FEX-Emu 前设置环境变量export FEX_ROOTFS_PATH/var/mobile/Containers/Data/Application/.../RootFS这个路径要指向应用沙盒内的 RootFS 目录。我建议在 Xcode 的 Scheme 里直接配好省得每次手动设。3.3 配置 Wine 前缀DLL 覆盖和注册表调整Wine 前缀创建好之后还需要做几项关键配置。首先是DLL 覆盖。DXMT 需要接管d3d11.dll、dxgi.dll和d3d10core.dll所以要在 Wine 注册表里把这些 DLL 设为原生加载WINEPREFIX~/.wine-madeira wine reg add \ HKEY_CURRENT_USER\Software\Wine\DllOverrides \ /v d3d11 /t REG_SZ /d native /f同样的命令把dxgi和d3d10core也设一遍。如果不设Wine 会用自己的 D3D 实现DXMT 就不会被加载。然后是Windows 版本。很多游戏检查系统版本如果发现是 Windows 7 就拒绝运行。我一般设成 Windows 10WINEPREFIX~/.wine-madeira winecfg在图形界面里选 Windows 10。如果 winecfg 跑不起来FEX-Emu 环境下有时会崩可以直接改注册表WINEPREFIX~/.wine-madeira wine reg add \ HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion \ /v CurrentVersion /t REG_SZ /d 10.0 /f还有一个常见问题是字体乱码。Wine 默认没有中文字体中文程序会显示成方块。解决办法是把系统的中文字体复制到 Wine 的字体目录cp /System/Library/Fonts/PingFang.ttc \ ~/.wine-madeira/drive_c/windows/Fonts/然后在注册表里把默认字体替换成 PingFangWINEPREFIX~/.wine-madeira wine reg add \ HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\FontSubstitutes \ /v MS Shell Dlg /t REG_SZ /d PingFang SC /f这样中文就能正常显示了。4. 性能调优与常见问题排查4.1 帧率上不去先检查这三个地方性能问题是最让人头疼的。我测试《空洞骑士》时一开始只有 15 帧后来逐步调到 45 帧。过程如下第一检查 JIT 是否真正启用。如果 FEX-Emu 跑在解释模式下性能会差 10 倍以上。你可以在 FEX-Emu 的日志里找JIT: enabled字样。如果没有说明 JIT 权限没生效需要重新检查dynamic-codesigning权限。第二调整 FEX-Emu 的翻译缓存大小。默认缓存是 128MB对于大型游戏不够用。可以在FEX_APP_CONFIG环境变量里设export FEX_APP_CONFIG{ThunkConfig:{CacheSize:536870912}}这里设了 512MB。缓存越大重复翻译越少但内存占用也越高。iPad Pro 有 8GB 或 16GB 内存512MB 完全没问题。第三关闭 Wine 的调试输出。Wine 默认会输出大量fixme和err日志这些日志写入磁盘会严重拖慢速度。在启动脚本里加export WINEDEBUG-all这一条就能提升 5-10 帧。4.2 常见问题速查表问题现象可能原因解决方法Wine 启动时报cannot open shared object fileRootFS 路径不对或库缺失检查FEX_ROOTFS_PATH确认 RootFS 内有lib/x86_64-linux-gnu游戏黑屏但有声音DXMT 未加载或着色器编译失败确认d3d11.dll已覆盖检查dxmt.conf的shader_cache_path是否可写中文显示为方块缺少中文字体复制 PingFang.ttc 到 Wine 字体目录并设置 FontSubstitutes程序随机卡死Wine 线程同步问题降级到 Wine 8.0.2或设置WINEDEBUG-all减少日志干扰JIT 未启用性能极差缺少dynamic-codesigning权限用 TrollStore 重新签名应用确保 entitlements 包含该权限DXMT 报Metal device creation failed应用没有 GPU 访问权限检查 Info.plist 是否包含UIRequiredDeviceCapabilities的metal键4.3 实操心得那些文档里不会写的东西第一个心得不要用最新版的 FEX-Emu。我试过 main 分支的最新提交结果 Wine 启动就崩。后来回退到 2024 年 3 月的 release 版本一切正常。FEX-Emu 的开发很活跃但新提交经常引入回归问题。建议用 tagged release。第二个心得DXMT 的着色器缓存要定期清理。缓存文件会越来越大有时候损坏的缓存会导致游戏花屏。我一般每周删一次shader_cache目录让游戏重新编译。虽然第一次会卡但总比花屏好。第三个心得iPad 的散热很重要。M1 跑 FEX-Emu 时功耗很高连续玩 20 分钟就会降频。我买了一个半导体散热背夹帧率稳定性提升明显。如果你只是偶尔玩玩可以忽略如果想长时间跑散热是必须的。第四个心得备份 Wine 前缀。配置好的 Wine 前缀很脆弱一次错误的 DLL 覆盖就可能导致整个环境崩溃。我现在的做法是配置完成后直接tar -czf wine-prefix-backup.tar.gz ~/.wine-madeira出问题就解压恢复省得重新配置。5. 还能怎么玩Madeira 的扩展可能性Madeira 目前主要跑 Windows 游戏但这套架构其实可以扩展。比如你可以用同样的 FEX-Emu Wine 组合跑Windows 版的开发工具像老版本的 Visual Studio 或者 Delphi。我试过跑 Delphi 7居然能启动只是界面渲染有点慢。另一个方向是Linux x86-64 应用。FEX-Emu 本身就能跑 x86-64 Linux 程序不一定非要经过 Wine。你可以直接在 RootFS 里装 x86-64 版的 Firefox 或者 GIMP然后通过 X11 转发显示到 iOS 上。不过 iOS 没有原生 X Server需要额外配置复杂度比较高。还有一个思路是结合 iOS 的自动化工具。比如用 Shortcuts 或者 Pythonista 写脚本自动启动 Madeira 环境并加载指定游戏。我写了一个简单的 Shortcut一键启动 FEX-Emu 并运行《星露谷物语》省得每次手动敲命令。最后提醒一句Madeira 目前还是实验性项目稳定性和兼容性都远不如桌面版的 Wine。如果你只是想玩 Windows 游戏建议直接用 PC 或者 Steam Deck。但如果你对跨架构翻译技术感兴趣Madeira 是一个非常好的学习平台能让你深入理解 JIT、API 翻译和图形栈的运作原理。