ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Madeira 兼容层实战:FEX-Emu、Wine 与 DXMT 跨平台运行指南

Madeira 兼容层实战:FEX-Emu、Wine 与 DXMT 跨平台运行指南 1. 从“Madeira”说起这个项目到底在折腾什么第一次看到“Madeira”这个名字很多人会以为是某个旅游项目或者葡萄酒品牌。但如果你混过模拟器、兼容层、跨平台运行这几个圈子就会知道这背后其实是一整套围绕FEX-Emu、Wine、DXMT构建的 x86-64 应用在非 x86 平台上的运行方案。简单说它想解决的问题是我手里有一堆为 Windows 和 x86-64 架构编译的软件、游戏、工具但我现在用的设备可能是 ARM 架构的或者系统本身不是 Windows怎么让这些东西跑起来而且跑得尽量稳、尽量快。这个标题下面挂着的热词非常杂FEX-Emu、Wine、DXMT、iOS、x86-64还有一堆关于 wine 乱码、麒麟 wine 助手、统信 wine 兼容组件、iOS 开发者模式、Xcode 上架流程、iOS 自动化、iOS 分屏、银行模拟器 iOS 等等。看起来像是把“跨平台兼容运行”和“iOS 开发/使用”两条线揉在了一起。实际上这两条线在“Madeira”这个项目里是有交集的一端是让 x86-64 的 Windows 程序在 ARM 设备上跑起来另一端是 iOS 生态里各种开发、调试、安装、上架、自动化的琐碎问题。我先把话说清楚这篇不是官方文档也不是什么“从入门到精通”的教程。它更像是一个折腾了很久的人把自己踩过的坑、试过的方案、最后跑通的路子整理出来。适合谁看如果你正在 ARM 设备上尝试运行 x86-64 的 Windows 软件或者你是一个 iOS 开发者/重度用户被开发者模式、证书、上架、WebView 播放、通知横幅这些东西搞得头大那这篇内容应该能帮你省下不少搜索时间。“Madeira”本身可以理解为一个兼容层组合方案的代称底层用 FEX-Emu 做 x86-64 到 ARM64 的指令翻译中间用 Wine 提供 Windows API 兼容环境图形层再用 DXMT 把 Direct3D 调用翻译成 Metal从而在 Apple 芯片设备上跑 Windows 游戏和软件。这个组合不是唯一解但它是目前社区里讨论比较多、迭代比较快的一条路线。下面我会把每个环节拆开讲包括为什么这么选、怎么配、哪里容易翻车。2. 核心组件拆解FEX-Emu、Wine、DXMT 各自扮演什么角色2.1 FEX-Emu把 x86-64 指令“翻译”成 ARM64 能听懂的话FEX-Emu 是一个开源的 x86-64 到 ARM64 的模拟/翻译层。它的核心思路不是像传统模拟器那样一条指令一条指令地解释执行而是做动态二进制翻译把 x86-64 的指令块翻译成 ARM64 的指令块然后缓存起来重复使用。这样做的好处是第一次执行某段代码时会有翻译开销但后续重复执行同一段代码时速度会接近原生。为什么在“Madeira”里需要它因为很多 Windows 软件和游戏只发布了 x86-64 版本没有 ARM64 版本。如果你用的是 Apple 芯片的 Mac、或者某些 ARM 架构的 Linux 设备这些程序本身是跑不起来的。FEX-Emu 就是那个“翻译官”让 CPU 能理解原本不认识的指令。实际使用中FEX-Emu 的配置有几个关键点。第一是RootFS也就是一个包含 x86-64 库和基础环境的文件系统镜像。没有它FEX-Emu 不知道去哪里找 x86-64 的动态链接库。第二是Thunking也就是把一些图形、音频、输入相关的调用直接转发给宿主系统的原生库避免在模拟环境里再模拟一遍。第三是JIT 缓存翻译结果会缓存到磁盘上下次启动会快很多。注意FEX-Emu 的 RootFS 版本要和 FEX-Emu 主程序版本匹配否则会出现库找不到或者符号不兼容的问题。我试过用旧版 RootFS 配新版 FEX-Emu结果 Wine 启动直接报错排查了半天才发现是版本对不上。2.2 Wine不是模拟器是 API 翻译层Wine 的全称是“Wine Is Not an Emulator”它做的事情是把 Windows 的系统调用翻译成宿主系统比如 Linux 或 macOS能理解的调用。它不模拟 CPU 指令所以它必须和 FEX-Emu 配合使用FEX-Emu 负责 CPU 指令翻译Wine 负责 Windows API 翻译。在“Madeira”方案里Wine 通常是以Wine64的形式运行在 FEX-Emu 的 RootFS 里面。也就是说你启动的是一个 x86-64 的 Wine它以为自己在一个 x86-64 的 Linux 环境里但实际上底层指令是被 FEX-Emu 翻译过的。Wine 的配置有几个绕不开的坑。首先是Wineprefix也就是模拟的 Windows 目录结构。每个 prefix 可以独立配置 Windows 版本、DLL 覆盖、注册表等。如果你要跑多个软件建议一个软件一个 prefix避免 DLL 冲突。其次是Winetricks用来安装一些 Windows 运行库比如 .NET、Visual C 运行库、DirectX 组件等。很多软件跑不起来不是 Wine 本身的问题而是缺了某个运行库。关于热词里提到的“wine 乱码”和“wine 栏是乱码”这通常是字体问题。Wine 默认的字体配置可能不包含中文字形导致菜单栏、对话框里的中文显示成方块或者乱码。解决办法是安装中文字体然后在 Wine 注册表里把默认字体替换成中文字体。具体操作后面会讲。2.3 DXMT把 Direct3D 翻译成 MetalDXMT 是一个把 Direct3D 11/12 调用翻译成 Metal 的项目。在 Apple 芯片设备上Metal 是原生的图形 API性能最好。如果没有 DXMTWine 里的 Direct3D 调用可能会走 OpenGL 或者 Vulkan 转译性能和兼容性都会打折扣。DXMT 在“Madeira”里的位置是Wine 收到游戏的 Direct3D 调用然后通过 DXMT 转发给 Metal最终由 GPU 执行。这个链路比原生 Windows 多了一层翻译所以性能损失是必然的但好的实现可以把损失控制在可接受范围内。实际使用中DXMT 需要和 Wine 的版本匹配也需要正确的 DLL 覆盖配置。通常需要把d3d11.dll、dxgi.dll等文件替换成 DXMT 提供的版本。如果配置不对游戏可能会黑屏、闪退或者报“找不到 d3d11.dll”。2.4 三者如何协同一个简化的数据流假设你启动一个 Windows 游戏整个流程大致是这样的你执行启动脚本FEX-Emu 加载 x86-64 的 Wine 可执行文件。Wine 读取 prefix 配置加载游戏的主程序。游戏调用 Direct3D 创建渲染设备Wine 把调用转给 DXMT。DXMT 把 Direct3D 调用翻译成 Metal 调用交给 Apple GPU 执行。游戏的输入、音频等调用由 Wine 转发给宿主系统的原生接口。这个链路里任何一环出问题游戏都跑不起来。所以排查问题时要一层一层看FEX-Emu 能不能跑简单的 x86-64 程序Wine 能不能启动记事本DXMT 能不能渲染简单的 Direct3D 测试程序每一步都确认了再上复杂的游戏。3. 实操环境搭建从零开始把“Madeira”跑起来3.1 硬件与系统前提“Madeira”方案主要面向 Apple 芯片的 MacM1/M2/M3/M4 系列因为 FEX-Emu 和 DXMT 在 macOS 上的适配相对成熟。系统版本建议 macOS 13 或更高低版本可能会有 Metal API 缺失的问题。内存建议 16GB 起步因为 FEX-Emu 的翻译缓存、Wine 的 prefix、游戏本身都会吃内存。硬盘空间至少留 50GBRootFS、Wine prefix、游戏安装目录加起来很容易超过这个数。如果你用的是 ARM 架构的 Linux 设备理论上也可以跑但 DXMT 的 Metal 后端就用不了了得换别的图形翻译方案。这篇主要按 macOS 路线讲Linux 路线只在必要处提一下。3.2 获取 FEX-Emu 和 RootFSFEX-Emu 的官方发布渠道会提供 macOS 的二进制包和对应的 RootFS。下载时注意看版本号主程序和 RootFS 要配套。解压后你会得到一个包含FEX可执行文件和RootFS目录的结构。RootFS 通常是一个压缩包解压后里面是一个完整的 Linux 文件系统包含/usr/lib/x86_64-linux-gnu等目录。你需要把这个 RootFS 放到 FEX-Emu 能找得到的位置通常是通过环境变量FEX_ROOTFS指定。export FEX_ROOTFS/path/to/RootFS export PATH/path/to/FEX:$PATH然后可以跑一个简单的测试FEX /path/to/RootFS/usr/bin/uname -m如果输出x86_64说明 FEX-Emu 已经能正常翻译 x86-64 指令了。这一步很关键如果这里就报错后面的 Wine 和 DXMT 都不用试了。3.3 在 RootFS 里配置 WineRootFS 里通常已经包含了 Wine但版本可能比较旧。你可以用 RootFS 里的包管理器更新或者手动下载新版 Wine 的 x86-64 二进制包放进去。配置 Wine 的第一步是创建 prefixexport WINEPREFIX/path/to/your/prefix FEX /path/to/RootFS/usr/bin/wineboot -uwineboot -u会初始化 prefix创建drive_c、注册表等。如果这一步卡住或者报错通常是 RootFS 里缺了某些库或者 FEX-Emu 的配置有问题。初始化完成后可以跑一个简单的 Windows 程序测试FEX /path/to/RootFS/usr/bin/wine notepad如果记事本窗口能弹出来说明 Wine 基本可用了。如果弹不出来看终端输出通常是缺 DLL 或者图形驱动没配好。3.4 配置 DXMTDXMT 的安装通常是把编译好的d3d11.dll、dxgi.dll、d3d10core.dll等文件复制到 Wine prefix 的drive_c/windows/system32目录然后在 Wine 注册表里设置 DLL 覆盖让 Wine 优先加载这些原生 DLL。具体步骤下载 DXMT 的发布包解压得到 DLL 文件。复制到$WINEPREFIX/drive_c/windows/system32/。运行winecfg在“函数库”标签页里把d3d11、dxgi等设置为“原生”优先。FEX /path/to/RootFS/usr/bin/winecfg配置完成后可以跑一个 Direct3D 测试程序比如dxdiag看看能不能正确识别渲染设备。如果dxdiag里显示的是 Metal 相关的设备信息说明 DXMT 已经生效了。3.5 安装和运行目标软件把 Windows 软件的安装包放到 prefix 能访问的目录然后运行安装程序FEX /path/to/RootFS/usr/bin/wine /path/to/installer.exe安装完成后用类似的方式启动主程序。如果软件需要特定的运行库可以用 Winetricks 安装FEX /path/to/RootFS/usr/bin/winetricks dotnet48 vcrun2019这里要注意Winetricks 本身是一个脚本它会在 RootFS 里下载和安装东西所以 RootFS 需要能访问网络或者你提前把安装包缓存好。4. 常见问题与排查技巧实录4.1 Wine 中文乱码怎么修这是热词里出现频率很高的问题。Wine 默认的字体替换表里中文字体可能映射到了不存在的字体导致中文显示为方块或乱码。解决办法分两步第一步把中文字体复制到 Wine 的字体目录cp /path/to/your/chinese/font.ttf $WINEPREFIX/drive_c/windows/Fonts/第二步修改注册表把默认字体替换成中文字体。可以创建一个.reg文件REGEDIT4 [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\FontSubstitutes] ArialNoto Sans CJK SC TahomaNoto Sans CJK SC MS Shell DlgNoto Sans CJK SC MS Shell Dlg 2Noto Sans CJK SC然后导入FEX /path/to/RootFS/usr/bin/wine regedit /path/to/font.reg重启 Wine 程序后中文应该就能正常显示了。如果还有个别地方乱码可能是那个程序自己带了字体文件需要单独替换。4.2 游戏黑屏或闪退黑屏和闪退的原因很多按概率从高到低排DXMT 没配好检查d3d11.dll和dxgi.dll是否在 system32 里DLL 覆盖是否设置正确。缺运行库用 Winetricks 装vcrun2019、dotnet48、d3dcompiler_47等。FEX-Emu 版本不匹配RootFS 和主程序版本不一致会导致奇怪的崩溃。游戏本身的反作弊或 DRM有些游戏有反作弊系统在模拟环境里会被检测为异常直接拒绝运行。这种基本无解除非游戏官方支持。排查时建议开 Wine 的调试输出WINEDEBUGd3d11,dxgi FEX /path/to/RootFS/usr/bin/wine game.exe看终端里哪一步报错然后针对性解决。4.3 性能调优的几个关键参数FEX-Emu 和 DXMT 都有一些影响性能的参数。FEX-Emu 这边可以调整 JIT 缓存大小和翻译线程数。DXMT 这边可以调整 Metal 的命令队列数量和着色器缓存策略。实际调优时我一般先跑一个基准测试记录帧率然后逐个调整参数看哪个参数对帧率影响最大。不要一次改一堆参数否则出了问题不知道是哪个引起的。另外macOS 的 Game Mode 对性能有影响建议开启。还有关闭后台不必要的应用尤其是那些吃 GPU 的能明显提升帧率稳定性。4.4 常见问题速查表问题现象可能原因排查方法解决方向Wine 启动报错找不到库RootFS 不完整或版本不匹配检查FEX_ROOTFS路径和版本重新下载配套 RootFS中文显示为方块字体缺失或替换表不对检查 Fonts 目录和注册表安装中文字体并修改替换表游戏黑屏DXMT 未生效跑dxdiag看渲染设备检查 DLL 覆盖和文件位置游戏闪退缺运行库或反作弊开WINEDEBUG看报错装运行库或放弃该游戏帧率过低翻译开销大或 GPU 瓶颈跑基准测试调参数调 JIT 缓存、关后台应用音频爆音或无声Wine 音频驱动配置问题检查winecfg音频设置切换音频驱动或装组件5. iOS 侧的那些事儿开发者模式、证书、上架与自动化5.1 iOS 开发者模式到底怎么开热词里反复出现“ios开发者模式”“ios 26.3.1怎么开发者模式”说明很多人卡在这一步。iOS 16 之后开发者模式默认是隐藏的需要先安装一个开发者证书或者用 Xcode 连接一次设备才能在设置里看到“开发者模式”选项。具体操作用数据线把 iPhone 连到 Mac打开 Xcode在“Window Devices and Simulators”里找到你的设备。Xcode 会提示需要开启开发者模式按照提示在 iPhone 上进入“设置 隐私与安全性 开发者模式”打开开关然后重启手机。重启后会有确认弹窗确认即可。如果设置里找不到“开发者模式”说明设备还没有被 Xcode 识别过。可以尝试重新连接、信任电脑、或者用 Apple Configurator 激活一下。5.2 免费证书与 Xcode 打包上架流程免费证书只能用于开发和真机调试不能上架 App Store。上架需要付费开发者账号个人或公司。从证书配置到上架的完整流程大致是在 Apple Developer 后台创建 App ID配置 Bundle ID 和所需能力。创建发布证书Distribution Certificate和描述文件Provisioning Profile。在 Xcode 里配置签名选择对应的 Team 和描述文件。Archive 打包上传到 App Store Connect。在 App Store Connect 里填写元数据、截图、隐私政策等。提交审核等待通过。常见坑点证书过期、描述文件不匹配、Bundle ID 冲突、隐私政策缺失、截图尺寸不对。Xcode 打包突然变慢通常是网络问题或者缓存问题可以清理 DerivedData 再试。5.3 iOS WebView 不能自动播放怎么办热词里有一条“抖音 ios webview 不能自动播放”这是 iOS 的默认策略WebView 里的音视频自动播放需要用户手势触发或者需要设置playsinline和muted属性。如果是在自己的 App 里嵌 WebView可以在WKWebViewConfiguration里设置mediaTypesRequiringUserActionForPlayback为[]允许自动播放。但注意App Store 审核可能会对自动播放有额外要求尤其是涉及广告的时候。5.4 仿 iOS 通知横幅与自动化“notification banner 仿 ios 通知横幅”这个需求通常出现在跨平台 App 或者网页里想模仿 iOS 的通知样式。实现思路是用 CSS 做圆角、毛玻璃背景、阴影然后用 JavaScript 控制滑入滑出动画。关键是要处理好安全区域safe area和不同屏幕尺寸的适配。iOS 自动化方面可以用快捷指令Shortcuts做很多重复性操作比如自动连接 Wi-Fi、自动发送消息、自动截图等。如果快捷指令不够用可以用 Xcode 写一个简单的 App调用XCUITest做 UI 自动化测试。再复杂一点可以用pymobiledevice3这类工具做设备管理自动化。6. 一些踩坑之后的个人体会折腾“Madeira”这套方案最大的感受是版本匹配比什么都重要。FEX-Emu、RootFS、Wine、DXMT、macOS 系统版本这五个东西只要有一个版本对不上就可能出现各种奇怪的问题。我建议你在升级任何一个组件之前先备份当前能用的配置然后一次只升一个确认没问题再升下一个。另一个体会是不要指望所有 Windows 软件都能跑。有些软件依赖特定的硬件驱动、反作弊系统、或者内核级组件这些在模拟环境里基本无解。与其花几个小时折腾一个跑不起来的软件不如先查查社区里有没有人成功跑过。如果没有人成功过大概率你也跑不起来。最后日志是你的朋友。Wine 的WINEDEBUG、FEX-Emu 的日志、DXMT 的日志这些输出虽然看起来很烦但里面往往藏着解决问题的关键线索。学会看日志比到处问人效率高得多。至于 iOS 那边开发者模式和证书配置是绕不过去的门槛但一旦配好了后面就是重复劳动。上架流程看起来复杂其实按部就班走一遍就熟了。WebView 自动播放和通知横幅这些都是细节问题查文档基本都能解决。这个内容后续还可以这样扩展比如把 FEX-Emu 换成其他 x86-64 翻译方案做对比测试或者把 DXMT 换成 Vulkan 转译方案看性能差异。如果你对某个环节特别感兴趣可以顺着那个方向深挖社区里相关的讨论和项目其实不少。
返回列表