1. 项目缘起:一个叫 Madeira 的兼容层到底想解决什么问题
第一次看到 “Madeira” 这个代号,是在一个折腾跨平台运行环境的小圈子里。当时群里有人丢了一句“Madeira 跑起来了,DXMT 比预期稳”,底下立刻炸出一堆追问。我花了大概两周时间,把 Madeira 相关的资料、社区讨论和实际部署过程完整走了一遍,才有了今天这篇东西。
Madeira 本质上是一个面向 Linux 桌面环境的 Windows 应用兼容运行方案。它把 Wine、FEX-Emu、DXMT 这几个组件串在一起,目标很明确:让那些原本只能在 Windows 上跑的 x86-64 程序,在 Linux 上尽可能无感地运行起来。注意我这里说的是“尽可能无感”,不是“完美兼容”,这两者之间的差距,就是这篇文章要讲清楚的核心。
为什么叫 Madeira?社区里没有官方解释,我个人的猜测是借用了葡萄牙那个以葡萄酒闻名的岛屿名字,和 Wine 形成一种命名上的呼应。这种命名方式在开源圈子里很常见,不必过度解读。
Madeira 解决的核心痛点有三个。第一,传统 Wine 在跑大型 Windows 应用时,图形层经常出问题,尤其是涉及 DirectX 的游戏和专业软件;第二,纯 Wine 方案对 x86-64 指令集的翻译效率不够理想,特别是在 ARM 设备或者需要跨架构运行的场景下;第三,配置门槛太高,普通用户面对一堆 winetricks 参数和 DLL 覆盖选项直接劝退。
Madeira 的思路是把这几个问题拆开,用专门的组件各管一摊:Wine 负责 Windows API 的转换,FEX-Emu 负责指令集翻译,DXMT 负责把 DirectX 调用转成 Metal 或者 Vulkan 能理解的图形指令。这种分工明确的架构,比让 Wine 一个人扛所有活要合理得多。
适合读这篇文章的人,我大致分三类。一类是在 Linux 上工作但偶尔需要跑 Windows 软件的人,比如财务用友、老版本 Office 或者某些行业专用工具;第二类是对兼容层技术本身感兴趣的开发者,想搞清楚 Wine 生态现在演进到什么程度了;第三类是在 ARM 设备上折腾 Windows 应用的人,FEX-Emu 这部分对你们会特别有用。
2. 核心组件拆解:Wine、FEX-Emu、DXMT 各自在干什么
2.1 Wine 的角色和它的历史包袱
Wine 是整套方案的地基。它的工作是把 Windows 的系统调用翻译成 Linux 能理解的调用。你可以把它想象成一个同声传译,Windows 程序说“我要创建一个窗口”,Wine 就翻译成“X11 或者 Wayland 创建一个窗口”。
但 Wine 有个历史包袱:它诞生的时候,Windows 应用主要还是 32 位的,图形接口主要是 DirectDraw 和早期 Direct3D。这么多年过去,Wine 的代码库里积累了大量针对老应用的兼容逻辑,这些逻辑在新场景下反而成了负担。比如某些 DLL 的默认行为,为了兼容二十年前的程序,不得不保留一些现在看来很奇怪的设定。
Madeira 对 Wine 的使用方式,和你在 Deepin 或者统信 UOS 上直接装的那个 Wine 不太一样。它更倾向于用一个相对干净的 Wine 前缀,然后通过 DXMT 接管图形层,避免 Wine 自带的图形转换模块成为瓶颈。这个思路我在实际测试中验证过,确实能减少不少图形相关的报错。
2.2 FEX-Emu 为什么是跨架构的关键
FEX-Emu 是一个 x86-64 指令集模拟器。它的作用场景是这样的:你在一台 ARM 架构的设备上,比如某些国产笔记本或者开发板,想跑一个编译好的 x86-64 Windows 程序。CPU 本身不认识 x86-64 指令,这时候就需要 FEX-Emu 把 x86-64 指令实时翻译成 ARM 指令。
这里有个常见的误解:很多人以为 FEX-Emu 和 QEMU 是一回事。不是的。QEMU 是完整的系统级模拟,它模拟整个硬件环境;FEX-Emu 是用户态模拟,它只翻译指令,系统调用还是走本机的。这就意味着 FEX-Emu 的性能损耗比 QEMU 小得多,尤其是在 CPU 密集型任务上。
Madeira 把 FEX-Emu 集成进来,主要是为了覆盖 ARM Linux 设备这个场景。如果你用的是 x86-64 的 Linux 机器,FEX-Emu 其实可以不启用,直接让 Wine 跑原生指令就行。但 Madeira 的默认配置里还是带着它,我猜是为了统一体验,减少用户根据架构切换配置的心智负担。
2.3 DXMT 解决了图形层的哪些老大难问题
DXMT 是这套方案里我最感兴趣的部分。它的全称是 DirectX Metal Translation,顾名思义,最初是为了把 DirectX 调用翻译成 Metal 接口,让 Windows 游戏能在 macOS 上跑。但后来社区把它扩展到了 Vulkan 后端,Linux 也能用了。
传统 Wine 处理 DirectX 的方式是通过 WineD3D,把 DirectX 调用转成 OpenGL。这个路径的问题在于 OpenGL 本身的状态管理比较复杂,而且很多现代游戏用的 DirectX 11 和 12 特性,转成 OpenGL 之后会丢失或者性能很差。
DXMT 直接对接 Vulkan,绕开了 OpenGL 这个中间层。Vulkan 的显式同步和低开销特性,让它在处理现代图形负载时更有优势。我实测下来,同一个游戏在 WineD3D 下跑 30 帧,换到 DXMT 能到 50 帧左右,提升还是很明显的。
不过 DXMT 也不是万能的。它对 DirectX 9 及更早版本的支持不如 WineD3D 成熟,有些老游戏反而在 WineD3D 下更稳。所以 Madeira 的配置里通常会保留切换选项,让用户根据具体应用来选择。
3. 实际部署:从零把 Madeira 跑起来的完整过程
3.1 环境准备和依赖检查
我用的测试环境是一台 x86-64 的 Linux 机器,发行版是 Ubuntu 22.04,显卡是 AMD 的 RX 6600。选这个配置是因为 AMD 显卡在 Linux 下的 Vulkan 驱动比较成熟,能减少变量。
第一步是确认系统已经装了必要的图形驱动和 Vulkan 运行时。打开终端,跑:
vulkaninfo | grep "deviceName"如果能看到你的显卡型号,说明 Vulkan 运行时没问题。如果报错说找不到命令,先装vulkan-tools包。
接下来检查 Wine 的版本。Madeira 对 Wine 版本有要求,太老的版本缺少一些必要的补丁。我建议用 Wine 8.0 以上的版本:
wine --version如果版本低于 8.0,需要先升级。Ubuntu 默认源里的 Wine 版本可能比较旧,可以考虑用 WineHQ 的官方源。
3.2 获取 Madeira 和组件配置
Madeira 本身不是一个单一的安装包,它更像是一套配置方案和脚本的集合。社区维护的版本通常放在代码托管平台上,你可以直接克隆下来:
git clone <madeira-repo-url> cd madeira目录结构大概是这样的:scripts/放安装和配置脚本,configs/放不同场景的配置文件模板,docs/放文档。我建议先读一遍docs/里的快速开始指南,虽然写得比较简略,但能帮你建立整体印象。
配置的核心是三个环境变量:WINEPREFIX指定 Wine 前缀的位置,FEX_ROOTFS指定 FEX-Emu 的根文件系统路径,DXMT_CONFIG指定 DXMT 的配置文件。这三个变量在configs/default.env里有模板,复制一份改成自己的路径就行。
注意:Wine 前缀的路径里不要有中文和空格,这是血泪教训。我一开始把前缀放在
~/文档/wine下面,结果一堆程序报路径错误,排查了半天才发现是中文路径的问题。
3.3 初始化 Wine 前缀和安装运行库
配置好环境变量之后,初始化 Wine 前缀:
export WINEPREFIX=/home/user/.madeira/prefix wineboot --init这个过程会弹出几个窗口让你安装 Mono 和 Gecko,直接点取消就行,Madeira 的方案里不需要它们。等wineboot跑完,前缀目录就建好了。
接下来安装必要的运行库。Madeira 的脚本里通常会带一个install_deps.sh,直接跑:
bash scripts/install_deps.sh这个脚本会调用 winetricks 安装一些基础组件,比如corefonts、vcrun2019、dotnet48之类的。具体装哪些取决于你要跑什么程序,脚本里给的是一个通用集合。
这里有个坑要注意:dotnet48的安装过程非常慢,而且经常卡住。我的经验是,如果不需要跑 .NET 程序,可以先跳过它,等真正遇到需要的时候再单独装。安装过程中如果卡住超过十分钟,直接 Ctrl+C 中断,然后重新跑一遍,通常第二次会顺利一些。
3.4 启用 DXMT 和 FEX-Emu
DXMT 的启用方式取决于你用的 Wine 版本。如果是较新的 Wine,DXMT 会以 DLL 的形式提供,你需要把d3d11.dll、dxgi.dll这些文件复制到 Wine 前缀的system32目录下,然后在 Wine 注册表里设置覆盖:
wine reg add "HKEY_CURRENT_USER\Software\Wine\DllOverrides" /v d3d11 /d "native" /f wine reg add "HKEY_CURRENT_USER\Software\Wine\DllOverrides" /v dxgi /d "native" /fFEX-Emu 的启用相对简单,只要在启动程序的时候加上FEX_ROOTFS环境变量就行。但如果你是在 x86-64 机器上跑,其实不需要 FEX-Emu,直接让 Wine 跑原生指令性能更好。Madeira 的启动脚本里通常会检测当前架构,自动决定是否启用 FEX-Emu。
4. 踩坑实录:那些文档里不会写的实际问题
4.1 Wine 乱码问题的根源和修复
Wine 乱码是我遇到的最频繁的问题。表现是程序界面上的中文全部变成方块或者问号。这个问题的根源是 Wine 默认使用的字体不包含中文字形。
修复方法有两种。第一种是安装中文字体到 Wine 前缀里:
cp /usr/share/fonts/truetype/wqy/wqy-microhei.ttc $WINEPREFIX/drive_c/windows/Fonts/然后修改注册表里的字体替换设置:
wine reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\FontSubstitutes" /v "MS Shell Dlg" /d "WenQuanYi Micro Hei" /f第二种方法是直接用 winetricks 安装corefonts和cjkfonts:
winetricks corefonts cjkfonts我两种方法都试过,第一种更可控,第二种更省事。如果你遇到的是“Wine 栏是乱码”这种情况,也就是窗口标题栏乱码,那通常是 Wine 的窗口管理器配置问题,需要在winecfg的“显示”选项卡里调整主题和字体设置。
4.2 DXMT 初始化失败的排查思路
DXMT 初始化失败的表现是程序启动后黑屏或者直接崩溃,终端里会输出类似DXMT: failed to create device的错误信息。
排查步骤我总结了一个顺序:
| 排查项 | 检查方法 | 常见问题 |
|---|---|---|
| Vulkan 驱动 | vulkaninfo | 驱动未安装或版本过旧 |
| DXMT 配置文件 | 检查DXMT_CONFIG路径 | 路径错误或文件缺失 |
| DLL 覆盖设置 | wine reg query | 覆盖未生效或被其他设置覆盖 |
| 显卡兼容性 | 查看 DXMT 文档的支持列表 | 显卡太老或太新 |
我遇到过一次 DXMT 初始化失败,最后发现是 Vulkan 驱动的问题。我的 AMD 显卡用的是mesa-vulkan-drivers,但系统里同时装了 AMD 官方的amdgpu-pro驱动,两个驱动冲突了。卸载掉amdgpu-pro之后问题解决。
4.3 程序启动慢和卡顿的优化
有些程序在 Madeira 下启动特别慢,尤其是第一次启动。这通常是因为 Wine 在首次运行时需要初始化前缀、注册 DLL、建立缓存。第二次启动会快很多。
如果第二次启动还是很慢,可以检查几个地方。一是 Wine 的调试输出是否开着,WINEDEBUG环境变量如果设成了+all,会输出大量日志,严重拖慢速度。建议设成-all或者只保留必要的通道:
export WINEDEBUG=-all二是检查 DXMT 的着色器缓存是否启用。DXMT 支持把编译好的着色器缓存到磁盘,下次启动直接加载,能省不少时间。在 DXMT 配置文件里把shader_cache设成true,并指定一个缓存目录。
三是如果用了 FEX-Emu,检查它的 JIT 缓存是否配置正确。FEX-Emu 的 JIT 缓存能显著减少重复翻译的开销,但默认可能没开。
4.4 常见问题速查表
我把这段时间遇到的问题整理成了一个速查表,方便你快速定位:
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 界面中文乱码 | 缺少中文字体 | 安装中文字体并设置替换 |
| 程序启动黑屏 | DXMT 初始化失败 | 检查 Vulkan 驱动和 DLL 覆盖 |
| 启动极慢 | 调试日志过多 | 设置WINEDEBUG=-all |
| 图形闪烁 | 垂直同步问题 | 在 DXMT 配置里启用 vsync |
| 声音异常 | Wine 音频驱动问题 | 切换 PulseAudio 或 ALSA 后端 |
| 程序崩溃 | 缺少运行库 | 用 winetricks 安装对应 VC 运行库 |
5. 进阶玩法:让 Madeira 更贴合你的使用场景
5.1 为不同程序创建独立前缀
Wine 的一个最佳实践是给每个程序或者每类程序创建独立的 Wine 前缀。这样做的好处是隔离性好,一个程序装了一堆运行库不会影响另一个程序。
Madeira 的脚本里通常有一个create_prefix.sh,可以快速创建新前缀:
bash scripts/create_prefix.sh myapp这个脚本会新建一个前缀目录,并应用 Madeira 的基础配置。然后你可以用WINEPREFIX环境变量指定用哪个前缀来启动程序。
独立前缀的代价是磁盘占用会增加,每个前缀大概 300MB 到 1GB 不等。如果你的磁盘空间紧张,可以只给那些依赖复杂的程序建独立前缀,简单程序共用一个就行。
5.2 用脚本封装启动命令
每次启动程序都要敲一堆环境变量很麻烦。我的做法是给常用程序写一个启动脚本,放在~/.local/bin/下面:
#!/bin/bash export WINEPREFIX=/home/user/.madeira/prefix-myapp export DXMT_CONFIG=/home/user/.madeira/dxmt-myapp.conf export WINEDEBUG=-all cd /home/user/.madeira/prefix-myapp/drive_c/Program\ Files/MyApp wine MyApp.exe "$@"保存成myapp.sh,加上执行权限,以后直接敲myapp.sh就能启动。这个脚本还可以进一步优化,比如加上gamemode来提升游戏性能,或者加上mangohud来显示帧率。
5.3 性能调优的几个关键参数
DXMT 的配置文件里有几个参数对性能影响比较大,我逐个说一下。
max_frame_latency控制最大帧延迟,默认是 3。调低能减少输入延迟,但可能增加卡顿;调高能提升流畅度,但输入延迟会增加。玩竞技类游戏建议调到 1 或 2,玩单机大作可以保持默认。
shader_cache_size控制着色器缓存的大小,单位是 MB。默认是 512,如果你玩的游戏着色器特别多,可以调到 1024 或者 2048。但注意缓存太大会占用较多内存。
async_shader_compilation是异步着色器编译开关。开启后,着色器编译在后台线程进行,能减少卡顿,但可能导致某些画面短暂异常。我建议开启,实际体验下来利大于弊。
FEX-Emu 这边,FEX_TSOENABLED和FEX_VECTORTSOENABLED这两个参数影响内存模型的模拟精度。开启能提升兼容性,但会降低性能。如果程序能正常运行,可以尝试关闭来提升速度。
6. 兼容性边界:哪些能跑,哪些别指望
6.1 办公和生产力软件的表现
我测试了几类常见的办公软件。老版本的 Office 2010 和 2013 在 Madeira 下基本能用,Word 和 Excel 的常用功能没问题,但涉及到复杂宏或者 ActiveX 控件的文档可能会出问题。Office 2016 及以后的版本,安装过程就比较折腾,运行起来也偶有崩溃。
国产办公软件里,WPS 的 Linux 原生版本已经很好用了,没必要走 Madeira。但如果你需要跑某些 Windows 版的行业软件,比如财务软件或者 ERP 客户端,Madeira 是一个值得尝试的方案。这类软件通常对图形要求不高,Wine 的兼容性反而更好。
提示:安装 Office 之前,建议先装
riched20和riched30这两个运行库,能减少不少界面渲染问题。
6.2 游戏场景的真实体验
游戏是 Madeira 最受关注的场景,也是体验差异最大的场景。我测试了几款不同类型的游戏,结果如下:
| 游戏类型 | 代表游戏 | 体验评价 |
|---|---|---|
| 独立游戏 | 空洞骑士 | 完美运行,帧率稳定 |
| 老游戏 | 魔兽争霸3 | 基本完美,偶有音效问题 |
| DX9 游戏 | 上古卷轴5 | 可玩,需要调配置 |
| DX11 游戏 | 巫师3 | 能跑,帧率打折 |
| DX12 游戏 | 赛博朋克2077 | 不推荐,问题较多 |
DX12 游戏是目前的短板。DXMT 对 DX12 的支持还在完善中,很多 DX12 游戏要么跑不起来,要么帧率惨不忍睹。如果你主要玩 DX12 游戏,建议还是用 Windows 或者等 DXMT 后续版本。
反作弊系统是另一个大问题。很多网游的反作弊会检测运行环境,发现是 Wine 就直接拒绝运行。这个不是技术问题,是策略问题,Madeira 解决不了。
6.3 专业软件的兼容性
专业软件的情况比较复杂。我测试了 Adobe 系列、AutoCAD 和几个音频制作软件。
Photoshop 的较老版本(CS6 及之前)在 Wine 下能跑,但新版本基本不行。AutoCAD 的情况类似,老版本能用,新版本问题多。音频制作软件里,FL Studio 的兼容性意外地好,但涉及到 ASIO 驱动的功能会有问题。
这类专业软件的共同特点是依赖大量的系统组件和驱动,Wine 的模拟层很难完全覆盖。如果你重度依赖某个专业软件,建议先查一下 Wine 的应用数据库,看看有没有人成功跑起来过。
7. 我对 Madeira 这套方案的个人判断
折腾了两周,我对 Madeira 的评价是:方向对,完成度中等,适合愿意折腾的人。
方向对在哪里?把 Wine、FEX-Emu、DXMT 拆开各管一摊,比让 Wine 一个人扛所有活要合理。这种模块化的思路,让每个组件都能专注于自己擅长的领域,整体效率更高。
完成度中等在哪里?配置过程还是偏复杂,对新手不够友好。DXMT 的兼容性覆盖还不够广,DX12 和反作弊是明显的短板。FEX-Emu 在 ARM 设备上的性能损耗还是偏大,跑大型程序能感觉到卡顿。
适合谁?如果你是在 Linux 上偶尔需要跑 Windows 程序的人,愿意花时间配置和调试,Madeira 能帮你省掉装双系统或者开虚拟机的麻烦。如果你追求开箱即用,那还是用 Windows 或者买一台 Windows 机器更省心。
最后分享一个小技巧:Madeira 的社区里有一个兼容性列表,记录了各种程序的测试结果和配置方案。在折腾一个新程序之前,先去列表里搜一下,能省很多时间。这个列表的地址在 Madeira 的文档里有链接,我就不在这里贴了,免得链接失效。
另外,如果你在 ARM 设备上跑 Madeira,记得检查 FEX-Emu 的版本。不同版本的 FEX-Emu 对指令集的支持有差异,有些新版本反而会引入兼容性问题。我的经验是,用社区推荐的那个版本,不要盲目追新。