Multipass 本地构建 QEMU 实战指南:从 vcpkg 默认切换到自编译的完整流程

发布时间:2026/9/25 18:22:49
Multipass 本地构建 QEMU 实战指南:从 vcpkg 默认切换到自编译的完整流程 虚拟化开发工具云原生【免费下载链接】multipassMultipass orchestrates virtual Ubuntu instances项目地址https://gitcode.com/gh_mirrors/mu/multipass点击查看免费下载Multipass 在 Linux 上默认通过 vcpkg 构建的 QEMU 提供虚拟化能力但在调试后端行为、验证新特性如 9p uid/gid 映射或排查虚拟机启动问题时开发者往往需要一套本地编译的 QEMU来替换系统自带二进制。本文以仓库内 building-and-using-a-locally-built-QEMU.md 为骨架完整梳理依赖安装、源码检出、configure 参数逐项解读、ninja 构建安装与最终验证的全流程并结合 QEMU 后端源码 与 vcpkg 构建脚本说明 Multipass 到底如何使用这些固件、ROM 与 9p 挂载能力帮助你构建出一套能被 Multipass 真正识别的本地 QEMU。背景为什么需要一套本地构建的 QEMU文档开篇明确指出一个关键事实Multipass 的 QEMU 默认由 vcpkg 提供即通过 3rd-party/vcpkg-ports/qemu/portfile.cmake 拉取上游源码、打上 Multipass 专属补丁后编译得到。日常使用无需关心这个过程但当你需要在 QEMU 源码层面调试 Multipass 的虚拟机启动、挂载或迁移问题验证尚未合入上游的新特性例如文档中提到的9p uid/gid 映射支持分支multipass-8.0.09p-uid-gid-map对比不同 QEMU 版本对固件、迁移状态兼容性的影响就需要在本地编译一套 QEMU并让它优先于系统/usr/bin下的版本被 Multipass 加载。文档也提醒了两点本指南可能在某些部分过时具体参数应以仓库中的 snap/snapcraft.yaml 和 vcpkg portfile 为准且整个过程面向 Linux 开发环境文档命令基于 apt 系发行版。第一步安装构建依赖本地编译 QEMU 需要一系列开发库。文档给出的安装命令如下sudo apt install libfdt-dev zlib1g-dev libsdl2-dev libgtk-3-dev \ libvte-dev libcapstone-dev libattr1-dev libcap-ng-dev \ libglib2.0-dev libpixman-1-dev libseccomp-dev meson libnfs-dev \ libiscsi-dev其中meson与ninja是 QEMU 现代构建系统meson 驱动、ninja 执行的核心libglib2.0-dev、libpixman-1-dev是 QEMU 的基础依赖glib 提供数据结构和事件循环pixman 提供图像合成libfdt-dev提供设备树解析libsdl2-dev/libgtk-3-dev/libvte-dev对应图形与终端前端libcap-ng-dev、libseccomp-dev用于安全能力限制与系统调用过滤libattr1-dev、libnfs-dev、libiscsi-dev、libcapstone-dev分别服务文件属性、NFS/iscsi 块设备协议与反汇编。文档也坦率说明并不确定哪些是必需项且多数依赖通常已存在。你可以对照 snap/snapcraft.yaml 中 multipass part 的build-packages列表其中包含ninja-build、build-essential、pkg-config、libglib2.0-dev等来确认最小依赖集合。若后续 configure 阶段报缺少某个库再按报错补齐即可不必一次性装齐。第二步获取 QEMU 源码并检出正确分支Multipass 使用的 QEMU 不是上游主线而是 Canonical 维护的定制分支。文档给出的做法git clone https://github.com/canonical/qemu.git can-qemu cd can-qemu git checkout -t origin/multipass-8.0.09p-uid-gid-map分支名multipass-8.0.09p-uid-gid-map中的9p-uid-gid-map指代 9p virtfs 文件共享的 uid/gid 映射能力——这正是 Multipass 原生挂载multipass mount在 QEMU 后端依赖的核心特性。如何确认当前仓库实际使用的分支文档给出的方法是查看snapcraft.yaml中 qemu part 的source-branch在本仓库中QEMU 的获取逻辑集中在 3rd-party/vcpkg-ports/qemu/portfile.cmake 的vcpkg_from_githubREF 为v${VERSION}而版本与源码分支由 3rd-party/vcpkg-ports/qemu/vcpkg.json 声明。更重要的是构建时会在上游源码上依次应用 6 个 Multipass 专属补丁multipass-patches0001-9p-uid-gid-mapping-support.patch9p uid/gid 映射支持与文档分支名对应的特性0002-revert-old-highmem-off-behavior.patch、0004-migration-remap-legacy-id-aa64pfr1-el1-key.patch、0006-migration-accept-subset-feature-id-registers.patch迁移/恢复兼容性修复0003-zero-initialize-vmnet-send-pos.patchmacOS vmnet 相关0005-disable-werror-for-dtc-subproject.patch关闭子项目-Werror以便构建。这意味着本地构建时如果直接使用上游分支而缺少这些补丁Multipass 的某些行为如旧实例恢复、9p 挂载可能与预期不符。本地构建主要用于调试建议对照 portfile 中的补丁列表评估差异。第三步配置构建configure 参数逐项解读在源码根目录创建独立构建目录并运行 configure 是最关键的一步。文档给出的完整命令mkdir build cd build ../configure \ --enable-virtfs \ --disable-bochs \ --disable-cloop \ --disable-docs \ --disable-guest-agent \ --disable-parallels \ --disable-qed \ --disable-libiscsi \ --disable-vnc \ --disable-xen \ --disable-dmg \ --disable-replication \ --disable-hax \ --disable-snappy \ --disable-lzo \ --disable-live-block-migration \ --disable-vvfat \ --disable-curl \ --disable-tests \ --disable-nettle \ --disable-libusb \ --disable-bzip2 \ --disable-gcrypt \ --disable-gnutls \ --disable-slirp \ --disable-user \ --disable-libvduse \ --disable-vduse-blk-export \ --enable-strip \ --firmwarepathshare/qemu:/usr/share/qemu \ --target-listx86_64-softmmu这批参数可以按职责分成几组理解1. 必须启用的核心特性--enable-virtfs开启 virtio 9p 文件系统后端这是 Multipassmount命令在 QEMU 后端实现原生挂载的前提。对应源码中 qemu_mount_handler.cpp 通过-virtfs参数启动挂载、并在实例内以mount -t 9p ... -o transvirtio,version9p2000.L,msize536870912完成的 9p 挂载流程。2. 构建目标裁剪--target-listx86_64-softmmu只编译x86_64系统级全系统模拟目标。文档明确指出省略该选项会为所有目标构建耗时显著增加也可换成其他目标列表。在 Multipass 的 vcpkg 构建中该值由架构自动推导——portfile.cmake 将x64映射为x86_64、arm64映射为aarch64并仅在启用systemfeature 时生成${QEMU_ARCH}-softmmu。大量--disable-*选项bochs、cloop、qed、parallels、dmg、vvfat 等磁盘镜像格式nettle、gcrypt、gnutls、bzip2、snappy、lzo、curl、libiscsi 等可选功能vnc、slirp、libusb、hax、xen、vduse 等设备/后端用于把构建面收窄到 Multipass 实际需要的范围显著缩短编译时间并减小二进制体积。这与 portfile 中QEMU_COMMON_OPTIONS列表portfile.cmake高度一致差异仅在 vcpkg 路径额外关闭了png、gtk、sdl、curses等显示相关项——本地构建若计划手动调试图形输出可以保留这些选项。3. 运行时环境适配--firmwarepathshare/qemu:/usr/share/qemu告诉 QEMU 到哪里查找固件默认值是相对--prefix的share/qemu。文档强调缺少该参数时 QEMU 无法找到vgabios-stdvga.bin这类 ROM而文档作者的系统还需要追加/usr/share/qemu以找到OVMF.fdUEFI 固件。不同发行版的固件安装位置不同需要按系统实际调整。--enable-strip安装时剥离调试符号减小二进制体积。4. 排障利器Bonus--enable-debug需要调试 QEMU 自身时追加该选项会关闭优化并保留符号信息代价是性能和体积。文档提醒除--target-list与--firmwarepath外其余选项再次查看我们当前使用的 yaml——即 snapcraft.yaml 与 portfile 中声明的参数。此外portfile 在 Linux 上还会追加--enable-kvmmacOS 上为--enable-hvf以及--extra-cflags/--extra-ldflags指向 vcpkg 安装目录portfile.cmake本地构建若需要 KVM 加速务必显式加上--enable-kvm。第四步构建与安装ninja、prefix 与 PATH 优先级configure 成功后直接以 ninja 构建ninja构建完成后需要把本地二进制安装到系统 PATH 中 apt 版 QEMU 之前的位置。首先确认默认安装前缀$ ../configure --help | grep \-\-prefix在文档作者的系统中默认前缀为/usr/local——因为/usr/local/bin在其PATH中位于/usr/bin之前安装后本地版自然覆盖 apt 版。若你的系统前缀不同可在 configure 阶段用--prefix指定但文档警告更换前缀后通常需要同步修改 Multipass 中 QEMU 的 AppArmor profile否则受限的 multipassd 进程可能无法访问新位置的可执行文件与固件。执行安装以及反向卸载sudo ninja install卸载使用sudo ninja uninstall。第五步验证本地 QEMU 生效安装完成后刷新 shell 的哈希缓存并确认调用的是新二进制hash -r which qemu-system-x86_64 qemu-system-x86_64 --versionhash -r用于清除 bash 对旧路径的缓存确保which与直接调用都能命中/usr/local/bin下的新版本。随后启动一个 Multipass 实例并尝试一次原生挂载multipass launch后multipass mount验证本地 QEMU 的 9p virtfs 能力在整个链路中正常工作——挂载实现细节可回溯到 qemu_mount_handler.cppMultipass 通过-virtfs local,pathhost,mount_tagtag,security_modelnone,multidevsremap参数启动 QEMU再在实例内用findmnt --type 9p检查挂载结果并通过 ssh 执行mount -t 9p ... -o transvirtio,version9p2000.L,msize536870912完成挂载。底层联动Multipass 后端如何使用固件、ROM 与 AppArmor要让本地构建的 QEMU 真正被 Multipass 正确驱动还需理解后端的几个关键消费点这也是--firmwarepath与 AppArmor 必须正确配置的根本原因固件路径QemuBaseProcessSpec::firmware_path()最终委托给QemuPlatform::firmware_path()见 qemu_base_process_spec.cpp 与 qemu_platform.h。Linux 后端会把 edk2 固件作为只读 pflash drive 加载qemu_platform_linux.cpp而恢复旧版本挂起的实例时还需要按版本兼容性选择固件参数qemu_vm_process_spec.cpp。vcpkg 构建会为不同架构选取对应固件x86_64 为edk2-x86_64-code.fd并额外打包旧版OVMF.fd以恢复旧实例见 portfile.cmake——本地构建时这些文件必须能被--firmwarepath找到。AppArmor 覆盖multipassd 以受限 snap 身份运行其 QEMU 进程使用基于/etc/apparmor.d/abstractions/libvirt-qemu生成的 profileqemu_vm_process_spec.cpp其中明确包含对固件目录的读取授权firmware firmware_path() /*。文档因此强调当--firmwarepath或--prefix偏离默认位置时必须同步调整 AppArmor profile 覆盖新路径否则 QEMU 即使装好也无法被 multipassd 启动。额外 ROM 资产除 UEFI 固件外系统模拟器运行时还需vgabios-stdvga.bin、kvmvapic.bin以及 virtio-net-pci 的 option ROMefi-virtio.rom。vcpkg portfile 会将这些资产与固件一并打包进Resources/qemuportfile.cmake并专门强调 efi-virtio.rom 的大小必须与挂起实例迁移状态匹配否则恢复会失败——本地构建时若固件/ROM 缺失或错位最常见的症状就是实例启动或恢复异常。常见问题与注意事项依赖缺失configure 阶段报错缺库时对照第一步清单按需补齐无需强制一次性装齐全部。固件找不到若报找不到vgabios-stdvga.bin或OVMF.fd优先检查--firmwarepath是否覆盖了固件实际所在目录Debian/Ubuntu 通常为/usr/share/qemu与/usr/share/OVMF。AppArmor 拦截本地 QEMU 无法从 multipassd 启动时检查 AppArmor profile 是否覆盖新的--prefix与固件路径此问题与文档引用的 Multipass PR 中apparmor profile 覆盖固件位置的修复同源。分支与补丁差异本地构建的源码分支可能缺少 vcpkg 构建所应用的 6 个补丁multipass-patches涉及 9p uid/gid 映射、迁移兼容性等行为调试时需留意差异。文档时效性configure 参数、源码分支等以 snapcraft.yaml 与 portfile.cmake 的当前声明为准本文与 原文档 均可能滞后于仓库演进。完成以上五步并理解后端的固件与权限约束后你就拥有了一套可被 Multipass 识别、可独立调试的本地 QEMU无论是排查虚拟机问题还是验证 9p 挂载等新特性都能在受控环境中快速迭代。赞分享虚拟化开发工具云原生【免费下载链接】multipassMultipass orchestrates virtual Ubuntu instances项目地址https://gitcode.com/gh_mirrors/mu/multipass点击查看免费下载相关推荐RustDesk 构建实战:从 vcpkg 依赖、Linux 原生编译到 Docker 构建的完整指南RustDesk 构建实战:从 vcpkg 依赖、Linux 原生编译到 Docker 构建的完整指南 本篇指南围绕 RustDesk 仓库中的 韩国语 REA音视频通信网络iii 通道Channels实战指南跨 Worker 流式传输大文件与二进制数据iii 通道Channels实战指南跨 Worker 流式传输大文件与二进制数据 导读 iii 的 Channels 是运行在引擎上、由 WebSocke虚拟化开发工具云原生DeepWiki-Open本地构建指南从源码编译到运行的完整流程DeepWiki Open本地构建指南从源码编译到运行的完整流程 项目简介 DeepWiki Open是一款AI驱动的Wiki生成工具能够为任何GitHubAI 应用人工智能RAG文档创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考