Hosts/W32: Difference between revisions
Stefan Weil (talk | contribs) |
|||
(27 intermediate revisions by 6 users not shown) | |||
Line 2: | Line 2: | ||
This documentation is work in progress - more information will be added as needed. | This documentation is work in progress - more information will be added as needed. | ||
While QEMU's main host platform is [[Hosts/Linux|Linux]], it is sometimes also useful to build or run it on members of the W32 / W64 family of operating systems (MS Windows | While QEMU's main host platform is [[Hosts/Linux|Linux]], it is sometimes also useful to build or run it on members of the W32 / W64 family of operating systems (MS Windows 8, Windows 10, Windows 11, ...) or on ReactOS (a W32 clone). Support for W64 was added in [[ChangeLog/1.1|QEMU 1.1]]. | ||
See https://www.qemu.org/docs/master/about/build-platforms.html#windows for information about which versions of Windows are currently supported. | |||
Please note that less developers work on QEMU for W32 / W64 hosts, so it might be less stable. | |||
Also note that the building process of QEMU involves some Python scripts that call os.symlink() which needs special attention for the build process to successfully complete. On newer versions of Windows 10, unprivileged accounts can create symlinks if Developer Mode is enabled. When Developer Mode is not available/enabled, the SeCreateSymbolicLinkPrivilege privilege is required, or the process must be run as an administrator. | |||
== Building QEMU for W32 == | == Building QEMU for W32 == | ||
Line 70: | Line 63: | ||
apt-get install g++-mingw-w64 mingw-w64 mingw-w64-tool mingw-w64-i686-dev mingw-w64-x86-64-dev nsis | apt-get install g++-mingw-w64 mingw-w64 mingw-w64-tool mingw-w64-i686-dev mingw-w64-x86-64-dev nsis | ||
In addition, several packages from Cygwin are needed ( | In addition, several packages from Cygwin are needed. Add https://qemu.weilnetz.de/debian/ as a package source (see instructions there) and install the required cross packages. | ||
==== Linux Mint based cross builds ==== | ==== Linux Mint based cross builds ==== | ||
Line 225: | Line 218: | ||
==== Fedora based cross builds ==== | ==== Fedora based cross builds ==== | ||
# Fedora cross | # Steps to cross-compile QEMU with 3D hardware acceleration on Fedora 40: | ||
# Get Qemu 9.1.0 source from the official site and unpack it: | |||
#: <code>wget https://download.qemu.org/qemu-9.1.0.tar.xz</code> | |||
#: <code>tar xvJf qemu-9.1.0.tar.xz</code> | |||
#: <code>cd qemu-9.1.0</code> | |||
# Run <code>sudo yum install git meson ninja-build python3-sphinx python3-sphinx_rtd_theme gcc mingw64-gcc mingw64-glib2 mingw64-pkg-config mingw64-pixman mingw64-gtk3 mingw64-SDL2 mingw64-libepoxy mingw64-librsvg2</code>. | |||
#: <code>mingw64-librsvg2</code> is optional, see step #11 | |||
# Get libslirp so that future qemu binaries can have internet access via <code>-netdev user</code> (e61dbd45 as of 04 August 2024): | |||
#: <code>git clone https://gitlab.freedesktop.org/slirp/libslirp.git</code> | |||
#; Get virgl to have 3D hardware acceleration (3d82ed86 as of 03 September 2024): | |||
#: <code>git clone https://gitlab.freedesktop.org/virgl/virglrenderer.git</code> | |||
# Create file <code>x86_64-w64-mingw32.txt</code> in <code>qemu-9.1.0</code> directory with the content as follows: | |||
[binaries] | |||
c = '/usr/bin/x86_64-w64-mingw32-gcc' | |||
cpp = '/usr/bin/x86_64-w64-mingw32-g++' | |||
ar = '/usr/bin/x86_64-w64-mingw32-ar' | |||
strip = '/usr/bin/x86_64-w64-mingw32-strip' | |||
pkg-config = '/usr/bin/x86_64-w64-mingw32-pkg-config' | |||
exe_wrapper = 'wine' | |||
[host_machine] | |||
system = 'windows' | |||
cpu_family = 'x86_64' | |||
cpu = 'i686' | |||
endian = 'little' | |||
# <li value="5"> Make a directory to which QEMU dependencies will be installed after compilation from git:</li> | |||
#: <code>export CROSS_QEMU_DEPS="/home/cross-qemu-deps"</code> | |||
#: <code>sudo mkdir -p $CROSS_QEMU_DEPS</code> | |||
# Install libslirp: | |||
#: <code>cd libslirp</code> | |||
#: <code>meson setup --cross-file ../x86_64-w64-mingw32.txt --prefix "$CROSS_QEMU_DEPS" build-mingw/</code> | |||
#: <code>meson compile -C build-mingw</code> | |||
#: <code>cd build-mingw</code> | |||
#: <code>ninja install</code> | |||
# Install virgl: | |||
#: <code>cd ../../</code> | |||
#: <code>cd virglrenderer</code> | |||
#: <code>meson setup --cross-file ../x86_64-w64-mingw32.txt --prefix "$CROSS_QEMU_DEPS" build-mingw/</code> | |||
#: <code>meson compile -C build-mingw</code> | |||
#: <code>cd build-mingw</code> | |||
#: <code>ninja install</code> | |||
# Set three environment variables for cross-compilation: | |||
#: Run <code>sudo find / -type f -name '*.pc'</code> and make sure all mingw *.pc files live in <code>/usr/x86_64-w64-mingw32/sys-root/mingw/share/pkgconfig/</code> and <code>/usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig/</code>. Correct these paths in PKG_CONFIG_PATH if you see they were altered by mingw or package contributors. | |||
#: <br> | |||
#: <code>export PKG_CONFIG_PATH="/usr/x86_64-w64-mingw32/sys-root/mingw/share/pkgconfig/:/usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig/:$PKG_CONFIG_PATH"</code> | |||
#: <br> | |||
#: <code>export PKG_CONFIG_LIBDIR="${CROSS_QEMU_DEPS}/lib/pkgconfig/:$PKG_CONFIG_LIBDIR"</code> | |||
#: <br> | |||
#: <code>export PKG_CONFIG_SYSROOT_DIR=""</code> | |||
# Configure Qemu makefile: | |||
#: <code>cd ../../</code> | |||
#: <code>./configure --cross-prefix=x86_64-w64-mingw32- --enable-gtk --enable-sdl --enable-opengl --enable-virglrenderer --enable-slirp --enable-debug</code> | |||
#: <br> | |||
#: and make sure you see this in the output of configure: | |||
#: <code>Compilation</code> | |||
#: <code>host CPU : x86_64</code> | |||
#: <code>host endianness : little</code> | |||
#: <code>C compiler : x86_64-w64-mingw32-gcc -m64</code> | |||
#: <code>Host C compiler : cc</code> | |||
#: <br> | |||
#: and this one: | |||
#: <code>Checking whether type "struct virgl_renderer_resource_info_ext" has member "d3d_tex2d" with dependency virglrenderer: YES</code> | |||
# Cross-compile qemu: <code>make -j`nproc`</code> | |||
# [optional step to get rid of '''"Gtk-WARNING **: 19:22:02.461: Could not load a pixbuf"'''] | |||
#: Copy '''gdk-pixbuf-query-loaders.exe''' from <code>/usr/x86_64-w64-mingw32/sys-root/mingw/bin/</code> | |||
#: to | |||
#: <code>./qemu-9.1.0/build/qemu-bundle/qemu</code> | |||
#: <br> | |||
#: Make folder for pixbuf: | |||
#: <code>mkdir -p ./qemu-9.1.0/build/qemu-bundle/qemu/lib</code> | |||
#: <br> | |||
#: Copy recursively <code>/usr/x86_64-w64-mingw32/sys-root/mingw/lib/gdk-pixbuf-2.0</code> folder into <code>./qemu-9.1.0/build/qemu-bundle/qemu/lib</code> | |||
#: <br> | |||
#: Make folder for default GTK icons and themes: | |||
#: <code>mkdir -p ./qemu-9.1.0/build/qemu-bundle/qemu/share</code> | |||
#: <br> | |||
#: Copy recursively <code>/usr/x86_64-w64-mingw32/sys-root/mingw/share/icons</code> folder into <code>./qemu-9.1.0/build/qemu-bundle/qemu/share</code> | |||
#: <br> | |||
#: Copy recursively <code>/usr/x86_64-w64-mingw32/sys-root/mingw/share/themes</code> folder into <code>./qemu-9.1.0/build/qemu-bundle/qemu/share</code> | |||
#: <br> | |||
#: Run <code>gdk-pixbuf-query-loaders.exe --update-cache</code> after transmitting compiled qemu to host Windows. | |||
# Copy all dll files from | |||
#: <code>/usr/x86_64-w64-mingw32/sys-root/mingw/bin/</code> | |||
#: to | |||
#: <code>./qemu-9.1.0/build/qemu-bundle/qemu</code> | |||
#: <br> | |||
#: Copy all dll files from <code>$CROSS_QEMU_DEPS</code> directory (including its subdirs) exported above to | |||
#: <code>./qemu-9.1.0/build/qemu-bundle/qemu</code> | |||
# Copy the '''qemu''' folder from the previous step to Windows machine using ssh (standard scp.exe utility) or whatever else. | |||
#: If your Fedora was launched in Qemu VM with '''-nic user,hostfwd=tcp::8888-:22''' command line parameter, you can transmit that compiled qemu folder to your host machine using the following way: | |||
#: Run these commands on guest Fedora: | |||
#: <code>sudo yum install openssh-server</code> | |||
#: <code>sudo systemctl start sshd</code> | |||
#: <code>sudo systemctl status sshd</code> | |||
#: And then run this command on host OS: | |||
#: <code>scp.exe -P 8888 -r virtual_machine_user@127.0.0.1:/home/virtual_machine_user/qemu-9.1.0/build/qemu-bundle/qemu C:\builds\qemu</code> | |||
<ol> | |||
<blockquote> | |||
'''<pre>Additional information</pre>''' | |||
Cross-compilation on Fedora build machine for Windows target usually requires installing pre-compiled binary packages along with libslirp and libvirglrenderer from git. Almost all of them include *.pc files (pkg-config files) needed by mingw to find .h headers and .dll.a library files. Normally, it's not necessarry to add extra include paths using something like CFLAGS="-I/include_headers_path" or LDFLAGS="-L/path_to_dll_a_lib". The commands from above must produce a fully working windows build. But, just in case someone damages packages in Fedora repository or libslirp or virglrenderer in their git, here are some ideas how to fix broken links between files: | |||
* First, make sure you have enumerated all .pc folders from Fedora repository packages in PKG_CONFIG_PATH= and all .pc folders built from source in PKG_CONFIG_LIBDIR=, as it was shown at Step 8. | |||
* If you see a message saying something like "virglrenderer.h not found", run this command to see where x86_64-w64-mingw32-pkg-config will look for virglrenderer.h: <code>/usr/bin/x86_64-w64-mingw32-pkg-config --cflags virglrenderer</code> | |||
<blockquote>-I/usr/x86_64-w64-mingw32/sys-root/mingw/usr/local/include/virgl (possible result)</blockquote> | |||
* Then copy folder containing virglrenderer.h (for example, /usr/local/include/virgl) to that one to satisfy mingw expectations: | |||
*: <code>sudo mkdir -p /usr/x86_64-w64-mingw32/sys-root/mingw/usr/local/include/</code> | |||
*: <code>sudo cp -r /usr/local/include/virgl /usr/x86_64-w64-mingw32/sys-root/mingw/usr/local/include/</code> | |||
* If you see "/usr/lib/gcc/x86_64-w64-mingw32/14.1.1/../../../../x86_64-w64-mingw32/bin/ld: cannot find -lvirglrenderer: No such file or directory" then most likely Qemu's makefile was confused by libvirglrenderer.dll.a path; check <code>/usr/x86_64-w64-mingw32/bin/ld -lvirglrenderer --verbose</code> output to find out path of libvirglrenderer.dll.a file it cannot find | |||
* For example, <code>/usr/x86_64-w64-mingw32/bin/ld -lvirglrenderer --verbose</code> shows that build script tries to find .dll.a file under /usr/x86_64-w64-mingw32/sys-root/usr/local/lib/libvirglrenderer.dll.a and <code>find / -type f -name 'libvirglrenderer.dll.a'</code> shows that file is in /usr/local/lib/libvirglrenderer.dll.a | |||
* Then satisfy mingw's expectation for libvirglrenderer.dll.a: | |||
*: <code>sudo mkdir -p /usr/x86_64-w64-mingw32/sys-root/usr/local/lib/</code> | |||
*: <code>sudo ln -s /usr/local/lib/libvirglrenderer.dll.a /usr/x86_64-w64-mingw32/sys-root/usr/local/lib/libvirglrenderer.dll.a</code> | |||
<br> | |||
The guide about cross-compilation on Fedora has been crafted in many ways thanks to the following sources:<br> | |||
https://gitlab.freedesktop.org/pkg-config/pkg-config/-/issues/52: | |||
<blockquote>PKG_CONFIG_SYSROOT_DIR blindly prepend the sysroot to all paths. I made a MR that add PKG_CONFIG_SYSROOT_MAP to get smarter mapping from pcfiledir->sysroot. !7. I generally discontinued the use of PKG_CONFIG_SYSROOT_DIR and switched to merely using PKG_CONFIG_LIBDIR. That way I got absolute paths everyehere which at least was consistent and could be postprocessed if needed.</blockquote> | |||
https://forum.qt.io/topic/88946/qt5-10-1-cross-compile-configure-errors/9: | |||
<blockquote>WARNING: Disabling pkg-config since PKG_CONFIG_LIBDIR is not set and the host's .pc files would be used (even if you set PKG_CONFIG_PATH). Set this variable to the directory that contains target .pc files for pkg-config to function correctly when cross-compiling or use -pkg-config to override this test.</blockquote> | |||
https://cmake.org/pipermail/cmake/2008-November/025050.html: | |||
<blockquote>The situation is as follows: PKG_CONFIG_PATH is searched before PKG_CONFIG_LIBDIR for the desired *.pc file. (The man page doesn't say which is searched first, but my tests reveal that is the order at least for the present version of pkg-config.) Cross-compiling users should avoid using native paths in PKG_CONFIG_PATH and PKG_CONFIG_LIBDIR. Furthermore, cross-compiling users should always specify PKG_CONFIG_LIBDIR (with or without PKG_CONFIG_PATH) since use of PKG_CONFIG_LIBDIR supresses appending default native paths to whatever is specified in PKG_CONFIG_PATH and PKG_CONFIG_LIBDIR. | |||
In sum, for cross-compilation purposes you should always use PKG_CONFIG_LIBDIR (with or without PKG_CONFIG_PATH) and make sure there are no native paths in it (or in PKG_CONFIG_PATH). If you follow those rules you should get a good cross-compilation result, otherwise not.</blockquote> | |||
</blockquote> | |||
</ol> | |||
==== Libraries (also needed for cross builds) ==== | ==== Libraries (also needed for cross builds) ==== | ||
Line 238: | Line 355: | ||
MSYS2 provides a convenient environment to produce native builds for W64. | MSYS2 provides a convenient environment to produce native builds for W64. | ||
* Download and run the MSYS2 installer from [ | * Download and run the MSYS2 installer from [https://www.msys2.org/]. | ||
* As per the MSYS2 documentation, download the latest repository updates with: | * As per the MSYS2 documentation, download the latest repository updates with: | ||
Line 250: | Line 367: | ||
* Next install the basic set of developer tools: | * Next install the basic set of developer tools: | ||
pacman -S base-devel mingw-w64-x86_64-toolchain git python | pacman -S base-devel mingw-w64-x86_64-toolchain git python ninja | ||
* Then install any required QEMU-specific packages. For a basic setup you can use: | * Then install any required QEMU-specific packages. For a basic setup you can use: | ||
pacman -S mingw-w64-x86_64-glib2 | pacman -S mingw-w64-x86_64-glib2 mingw-w64-x86_64-pixman python-setuptools | ||
* Additional optional features require more packages. For example, to enable GTK+ and SDL user interface and user networking you can use: | |||
pacman -S mingw-w64-x86_64-gtk3 mingw-w64-x86_64-SDL2 mingw-w64-x86_64-libslirp | |||
git clone | * Close the MSYS2 console. | ||
* Start ucrt64.exe. | |||
* Download the QEMU source code: | |||
git clone https://gitlab.com/qemu-project/qemu.git | |||
* Finally build QEMU | * Finally build QEMU with: | ||
./configure --enable-gtk --enable- | cd qemu | ||
./configure --enable-sdl --enable-gtk --enable-slirp | |||
make | make | ||
Line 282: | Line 403: | ||
and those which I tried, namely x86 and mips, work well). | and those which I tried, namely x86 and mips, work well). | ||
Hardware acceleration for x86 can be enabled with the command line option <code>--enable- | Hardware acceleration for x86 can be enabled with the command line option <code>--enable-whpx</code>. | ||
=== Special W32 devices === | === Special W32 devices === | ||
Line 293: | Line 413: | ||
Text which is normally printed by QEMU to the console output channels (normally known as standard output = stdout and standard error output = stderr) might be written to files called stdout.txt and stderr.txt if QEMU was linked with SDL 1.2. | Text which is normally printed by QEMU to the console output channels (normally known as standard output = stdout and standard error output = stderr) might be written to files called stdout.txt and stderr.txt if QEMU was linked with SDL 1.2. | ||
If you want to see QEMU's help messages or if it does not work as expected, you should look for these files in the directory where your exe file is installed. | If you want to see QEMU's help messages or if it does not work as expected, you should look for these files in the directory where your exe file is installed. | ||
== Running QEMU for W64 == | |||
== Links == | == Links == | ||
;Mingw-w64 Website (supports both 32 and 64 bit builds) | ;Mingw-w64 Website (supports both 32 and 64 bit builds) | ||
Line 305: | Line 424: | ||
:http://www.gtk.org/download/win32.php | :http://www.gtk.org/download/win32.php | ||
:http://www.gtk.org/download/win64.php | :http://www.gtk.org/download/win64.php | ||
Latest revision as of 19:23, 13 October 2024
QEMU on W32 and W64 hosts
This documentation is work in progress - more information will be added as needed.
While QEMU's main host platform is Linux, it is sometimes also useful to build or run it on members of the W32 / W64 family of operating systems (MS Windows 8, Windows 10, Windows 11, ...) or on ReactOS (a W32 clone). Support for W64 was added in QEMU 1.1. See https://www.qemu.org/docs/master/about/build-platforms.html#windows for information about which versions of Windows are currently supported.
Please note that less developers work on QEMU for W32 / W64 hosts, so it might be less stable.
Also note that the building process of QEMU involves some Python scripts that call os.symlink() which needs special attention for the build process to successfully complete. On newer versions of Windows 10, unprivileged accounts can create symlinks if Developer Mode is enabled. When Developer Mode is not available/enabled, the SeCreateSymbolicLinkPrivilege privilege is required, or the process must be run as an administrator.
Building QEMU for W32
QEMU for W32 needs a fairly complete Mingw-w64 based development environment with tools (make, compiler, linker, ...) and some additional libraries. Building with the older MinGW does not work!
Cross builds
Compilation of QEMU for W32 on non-W32 hosts (e.g. Linux hosts) is called cross compilation. Some Linux distributions (Debian, Ubuntu, Fedora and maybe others) already include packages needed for cross compilation, so the installation of these packages is the first step.
Debian squeeze based cross builds
Note: Building on Debian squeeze is no longer supported, so the following commands won't work with latest QEMU.
# Debian squeeze for W32: apt-get install gcc-mingw32 mingw32-binutils mingw32-runtime
# Debian (squeeze?) for W64: apt-get install gcc-mingw32 mingw32-binutils mingw-w64
SDL support is not included in standard MinGW, but packages for MinGW are available on the SDL homepage. POSIX thread support is not included in Debian or Ubuntu. Latest QEMU will need it, so you have to get it from MinGW (see links below).
Cross compilers usually are installed in /usr/bin with a prefix. For Debian, the cross gcc is called i586-mingw32msvc-gcc. This cross prefix must be passed to QEMU's configure.
# Debian cross configuration for W32: configure --cross-prefix=i586-mingw32msvc- [--extra-cflags=-mthreads]
Compiler option is needed for gcc versions which don't support TLS (thread local storage) without it (version 4.4 which is Debian's default needs it!).
Debian does not include a cross pkg-config, but it is required for cross builds. The following script can be saved as /usr/bin/i586-mingw32msvc-pkg-config and optionally be linked to /usr/bin/amd64-mingw32msvc-pkg-config.
#!/bin/sh basename=`basename $0` prefix=/usr/`echo $basename|sed s/-pkg-config//` PKG_CONFIG_LIBDIR=$prefix/lib/pkgconfig export PKG_CONFIG_LIBDIR pkg-config --define-variable=prefix=$prefix $@
Debian stretch based cross builds
# Debian stretch for W32 and W64: apt-get install g++-mingw-w64 mingw-w64 mingw-w64-tool mingw-w64-i686-dev mingw-w64-x86-64-dev nsis
In addition, several packages from Cygwin are needed. Add https://qemu.weilnetz.de/debian/ as a package source (see instructions there) and install the required cross packages.
Linux Mint based cross builds
These instructions were tested with the Linux Mint Debian Edition on 2012-06-02.
# Linux Mint for W32 and W64 (about 463 MiB): apt-get install mingw-w64
OpenSUSE based cross builds
Add http://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_11.4 (update with your release version) to the list of software repositories. Then install at least the following packets (most of them are pulled via dependencies):
mingw32-binutils mingw32-cpp mingw32-cross-binutils mingw32-cross-cpp mingw32-cross-gcc mingw32-cross-pkg-config mingw32-filesystem mingw32-gcc mingw32-glib2 mingw32-glib2-devel mingw32-glib2-lang mingw32-headers mingw32-libgcc mingw32-libgmp mingw32-libintl mingw32-libintl-devel mingw32-libmpc mingw32-libmpfr mingw32-libSDL mingw32-libSDL-devel mingw32-libssp mingw32-runtime mingw32-zlib mingw32-zlib-devel
This toolchain does not include libiberty.a in its binutils package, but it also does not need to. If building against a QEMU version that still pulls this in unconditionally, simply drop the -liberty
from configure.
For W64 use the corresponding win64 repository and mingw64- packages.
Fedora based cross builds
Fedora supports both W64 and W32 cross builds.
# Fedora for W32 cross build: dnf install mingw32-pixman mingw32-glib2 mingw32-gmp mingw32-SDL2 mingw32-pkg-config
# Fedora for W64 cross build: dnf install mingw64-pixman mingw64-glib2 mingw64-gmp mingw64-SDL2 mingw64-pkg-config
Cross compilers usually are installed in /usr/bin with a prefix. This cross prefix must be passed to QEMU's configure. The prefix depends on your target platform.
For Fedora W64 builds, the cross gcc is called x86_64-w64-mingw32-gcc.
# Fedora cross configuration for W64: ./configure --cross-prefix=x86_64-w64-mingw32-
For Fedora W32 builds, the cross gcc is called i686-w64-mingw32-gcc.
# Fedora cross configuration for W32: ./configure --cross-prefix=i686-w64-mingw32-
Note that "-mingw32-w64" appears in prefix for both W32 and W64 builds.
Docker based cross builds
As of June 2016, the master tree supports "docker based compiling", which can be used for convenient windows cross build.
Make sure your docker command works ("docker ps" or "sudo docker ps" reports no error), then cd into the root of QEMU source tree and run
make docker-test-mingw@fedora V=1 DEBUG=1 J=4
, it will download and initialize the needed docker image for you, and drop you into a shell in the started container. Run
cd $QEMU_SRC
then
./configure --cross-prefix=x86_64-w64-mingw32-
or
./configure --cross-prefix=i686-w64-mingw32-
for 64bit/32bit builds respectively.
Native builds with Mingw-w64
Get and install Mingw-w64. In addition, some more packages are needed:
Libraries (also needed for cross builds)
- GLib Run-time (http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.28/glib_2.28.1-1_win32.zip)
- GLib Development (http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.28/glib-dev_2.28.1-1_win32.zip)
- gettext-runtime Development (http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/gettext-runtime-dev_0.18.1.1-2_win32.zip)
Tools (only needed for native builds)
Get the QEMU source code (git or tarball), then run configure and make.
Native builds with Cygwin
Builds with the normal Cygwin compiler are not supported. Nevertheless, cygwin can be used as a build environment because it also contains all necessary Mingw-w64 packages.
# Don't build in the QEMU source directory. Using a subdirectory is better. # Here is an example of a debug build. SRC_PATH=$PWD BUILD_DIR=$PWD/bin/debug/i686-w64-mingw32 mkdir -p $BUILD_DIR cd $BUILD_DIR $SRC_PATH/configure' '--enable-debug' '--cross-prefix=i686-w64-mingw32-' make
For 32 bit builds, these packages should be installed:
Required packages
- mingw64-i686-gcc-g++
- mingw64-i686-glib2.0
- mingw64-i686-pixman
- mingw64-i686-pkg-config
Recommended packages
- mingw64-i686-curl
- mingw64-i686-gtk3
- mingw64-i686-libssh2
- mingw64-i686-libtasn1
- mingw64-i686-nettle
- mingw64-i686-ncurses
- mingw64-i686-gnutls
Optional packages
- mingw64-i686-SDL2
- mingw64-i686-libgcrypt
- mingw64-i686-libusb1.0
- mingw64-i686-usbredir
Building QEMU for W64
QEMU for W64 needs a fairly complete MinGW-w64 based development environment with tools (make, compiler, linker, ...) and some additional libraries.
Cross builds
Compilation of QEMU for W64 on non-W64 hosts (e.g. Linux hosts) is called cross compilation. Some Linux distributions (Debian, Ubuntu, Fedora and maybe others) already include packages needed for cross compilation, so the installation of these packages is the first step.
Debian based cross builds
# Debian cross configuration for W64: configure --cross-prefix=amd64-mingw32msvc-
Fedora based cross builds
# Steps to cross-compile QEMU with 3D hardware acceleration on Fedora 40:
- Get Qemu 9.1.0 source from the official site and unpack it:
wget https://download.qemu.org/qemu-9.1.0.tar.xz
tar xvJf qemu-9.1.0.tar.xz
cd qemu-9.1.0
- Run
sudo yum install git meson ninja-build python3-sphinx python3-sphinx_rtd_theme gcc mingw64-gcc mingw64-glib2 mingw64-pkg-config mingw64-pixman mingw64-gtk3 mingw64-SDL2 mingw64-libepoxy mingw64-librsvg2
.mingw64-librsvg2
is optional, see step #11
- Get libslirp so that future qemu binaries can have internet access via
-netdev user
(e61dbd45 as of 04 August 2024):git clone https://gitlab.freedesktop.org/slirp/libslirp.git
- Get virgl to have 3D hardware acceleration (3d82ed86 as of 03 September 2024)
git clone https://gitlab.freedesktop.org/virgl/virglrenderer.git
- Create file
x86_64-w64-mingw32.txt
inqemu-9.1.0
directory with the content as follows:
[binaries] c = '/usr/bin/x86_64-w64-mingw32-gcc' cpp = '/usr/bin/x86_64-w64-mingw32-g++' ar = '/usr/bin/x86_64-w64-mingw32-ar' strip = '/usr/bin/x86_64-w64-mingw32-strip' pkg-config = '/usr/bin/x86_64-w64-mingw32-pkg-config' exe_wrapper = 'wine' [host_machine] system = 'windows' cpu_family = 'x86_64' cpu = 'i686' endian = 'little'
- Make a directory to which QEMU dependencies will be installed after compilation from git:
export CROSS_QEMU_DEPS="/home/cross-qemu-deps"
sudo mkdir -p $CROSS_QEMU_DEPS
- Install libslirp:
cd libslirp
meson setup --cross-file ../x86_64-w64-mingw32.txt --prefix "$CROSS_QEMU_DEPS" build-mingw/
meson compile -C build-mingw
cd build-mingw
ninja install
- Install virgl:
cd ../../
cd virglrenderer
meson setup --cross-file ../x86_64-w64-mingw32.txt --prefix "$CROSS_QEMU_DEPS" build-mingw/
meson compile -C build-mingw
cd build-mingw
ninja install
- Set three environment variables for cross-compilation:
- Run
sudo find / -type f -name '*.pc'
and make sure all mingw *.pc files live in/usr/x86_64-w64-mingw32/sys-root/mingw/share/pkgconfig/
and/usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig/
. Correct these paths in PKG_CONFIG_PATH if you see they were altered by mingw or package contributors. export PKG_CONFIG_PATH="/usr/x86_64-w64-mingw32/sys-root/mingw/share/pkgconfig/:/usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig/:$PKG_CONFIG_PATH"
export PKG_CONFIG_LIBDIR="${CROSS_QEMU_DEPS}/lib/pkgconfig/:$PKG_CONFIG_LIBDIR"
export PKG_CONFIG_SYSROOT_DIR=""
- Run
- Configure Qemu makefile:
cd ../../
./configure --cross-prefix=x86_64-w64-mingw32- --enable-gtk --enable-sdl --enable-opengl --enable-virglrenderer --enable-slirp --enable-debug
- and make sure you see this in the output of configure:
Compilation
host CPU : x86_64
host endianness : little
C compiler : x86_64-w64-mingw32-gcc -m64
Host C compiler : cc
- and this one:
Checking whether type "struct virgl_renderer_resource_info_ext" has member "d3d_tex2d" with dependency virglrenderer: YES
- Cross-compile qemu:
make -j`nproc`
- [optional step to get rid of "Gtk-WARNING **: 19:22:02.461: Could not load a pixbuf"]
- Copy gdk-pixbuf-query-loaders.exe from
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/
- to
./qemu-9.1.0/build/qemu-bundle/qemu
- Make folder for pixbuf:
mkdir -p ./qemu-9.1.0/build/qemu-bundle/qemu/lib
- Copy recursively
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/gdk-pixbuf-2.0
folder into./qemu-9.1.0/build/qemu-bundle/qemu/lib
- Make folder for default GTK icons and themes:
mkdir -p ./qemu-9.1.0/build/qemu-bundle/qemu/share
- Copy recursively
/usr/x86_64-w64-mingw32/sys-root/mingw/share/icons
folder into./qemu-9.1.0/build/qemu-bundle/qemu/share
- Copy recursively
/usr/x86_64-w64-mingw32/sys-root/mingw/share/themes
folder into./qemu-9.1.0/build/qemu-bundle/qemu/share
- Run
gdk-pixbuf-query-loaders.exe --update-cache
after transmitting compiled qemu to host Windows.
- Copy gdk-pixbuf-query-loaders.exe from
- Copy all dll files from
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/
- to
./qemu-9.1.0/build/qemu-bundle/qemu
- Copy all dll files from
$CROSS_QEMU_DEPS
directory (including its subdirs) exported above to ./qemu-9.1.0/build/qemu-bundle/qemu
- Copy the qemu folder from the previous step to Windows machine using ssh (standard scp.exe utility) or whatever else.
- If your Fedora was launched in Qemu VM with -nic user,hostfwd=tcp::8888-:22 command line parameter, you can transmit that compiled qemu folder to your host machine using the following way:
- Run these commands on guest Fedora:
sudo yum install openssh-server
sudo systemctl start sshd
sudo systemctl status sshd
- And then run this command on host OS:
scp.exe -P 8888 -r virtual_machine_user@127.0.0.1:/home/virtual_machine_user/qemu-9.1.0/build/qemu-bundle/qemu C:\builds\qemu
- First, make sure you have enumerated all .pc folders from Fedora repository packages in PKG_CONFIG_PATH= and all .pc folders built from source in PKG_CONFIG_LIBDIR=, as it was shown at Step 8.
- If you see a message saying something like "virglrenderer.h not found", run this command to see where x86_64-w64-mingw32-pkg-config will look for virglrenderer.h:
/usr/bin/x86_64-w64-mingw32-pkg-config --cflags virglrenderer
- Then copy folder containing virglrenderer.h (for example, /usr/local/include/virgl) to that one to satisfy mingw expectations:
sudo mkdir -p /usr/x86_64-w64-mingw32/sys-root/mingw/usr/local/include/
sudo cp -r /usr/local/include/virgl /usr/x86_64-w64-mingw32/sys-root/mingw/usr/local/include/
- If you see "/usr/lib/gcc/x86_64-w64-mingw32/14.1.1/../../../../x86_64-w64-mingw32/bin/ld: cannot find -lvirglrenderer: No such file or directory" then most likely Qemu's makefile was confused by libvirglrenderer.dll.a path; check
/usr/x86_64-w64-mingw32/bin/ld -lvirglrenderer --verbose
output to find out path of libvirglrenderer.dll.a file it cannot find - For example,
/usr/x86_64-w64-mingw32/bin/ld -lvirglrenderer --verbose
shows that build script tries to find .dll.a file under /usr/x86_64-w64-mingw32/sys-root/usr/local/lib/libvirglrenderer.dll.a andfind / -type f -name 'libvirglrenderer.dll.a'
shows that file is in /usr/local/lib/libvirglrenderer.dll.a - Then satisfy mingw's expectation for libvirglrenderer.dll.a:
sudo mkdir -p /usr/x86_64-w64-mingw32/sys-root/usr/local/lib/
sudo ln -s /usr/local/lib/libvirglrenderer.dll.a /usr/x86_64-w64-mingw32/sys-root/usr/local/lib/libvirglrenderer.dll.a
Additional informationCross-compilation on Fedora build machine for Windows target usually requires installing pre-compiled binary packages along with libslirp and libvirglrenderer from git. Almost all of them include *.pc files (pkg-config files) needed by mingw to find .h headers and .dll.a library files. Normally, it's not necessarry to add extra include paths using something like CFLAGS="-I/include_headers_path" or LDFLAGS="-L/path_to_dll_a_lib". The commands from above must produce a fully working windows build. But, just in case someone damages packages in Fedora repository or libslirp or virglrenderer in their git, here are some ideas how to fix broken links between files:
-I/usr/x86_64-w64-mingw32/sys-root/mingw/usr/local/include/virgl (possible result)
The guide about cross-compilation on Fedora has been crafted in many ways thanks to the following sources:
https://gitlab.freedesktop.org/pkg-config/pkg-config/-/issues/52:PKG_CONFIG_SYSROOT_DIR blindly prepend the sysroot to all paths. I made a MR that add PKG_CONFIG_SYSROOT_MAP to get smarter mapping from pcfiledir->sysroot. !7. I generally discontinued the use of PKG_CONFIG_SYSROOT_DIR and switched to merely using PKG_CONFIG_LIBDIR. That way I got absolute paths everyehere which at least was consistent and could be postprocessed if needed.
https://forum.qt.io/topic/88946/qt5-10-1-cross-compile-configure-errors/9:
WARNING: Disabling pkg-config since PKG_CONFIG_LIBDIR is not set and the host's .pc files would be used (even if you set PKG_CONFIG_PATH). Set this variable to the directory that contains target .pc files for pkg-config to function correctly when cross-compiling or use -pkg-config to override this test.
https://cmake.org/pipermail/cmake/2008-November/025050.html:
The situation is as follows: PKG_CONFIG_PATH is searched before PKG_CONFIG_LIBDIR for the desired *.pc file. (The man page doesn't say which is searched first, but my tests reveal that is the order at least for the present version of pkg-config.) Cross-compiling users should avoid using native paths in PKG_CONFIG_PATH and PKG_CONFIG_LIBDIR. Furthermore, cross-compiling users should always specify PKG_CONFIG_LIBDIR (with or without PKG_CONFIG_PATH) since use of PKG_CONFIG_LIBDIR supresses appending default native paths to whatever is specified in PKG_CONFIG_PATH and PKG_CONFIG_LIBDIR. In sum, for cross-compilation purposes you should always use PKG_CONFIG_LIBDIR (with or without PKG_CONFIG_PATH) and make sure there are no native paths in it (or in PKG_CONFIG_PATH). If you follow those rules you should get a good cross-compilation result, otherwise not.
Libraries (also needed for cross builds)
- GLib Run-time (http://ftp.gnome.org/pub/gnome/binaries/win64/glib/2.22/glib_2.22.4-1_win64.zip)
- GLib Development (http://ftp.gnome.org/pub/gnome/binaries/win64/glib/2.22/glib-dev_2.22.4-1_win64.zip) - newer versions don't work because leading underscores for global symbols are missing
- gettext-runtime Development (http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/gettext-runtime-dev_0.18.1.1-2_win64.zip)
Native builds with MSYS2
MSYS2 provides a convenient environment to produce native builds for W64.
- Download and run the MSYS2 installer from [1].
- As per the MSYS2 documentation, download the latest repository updates with:
pacman -Syu
- If required, restart the MSYS2 console. Then update the remaining packages with:
pacman -Su
- Next install the basic set of developer tools:
pacman -S base-devel mingw-w64-x86_64-toolchain git python ninja
- Then install any required QEMU-specific packages. For a basic setup you can use:
pacman -S mingw-w64-x86_64-glib2 mingw-w64-x86_64-pixman python-setuptools
- Additional optional features require more packages. For example, to enable GTK+ and SDL user interface and user networking you can use:
pacman -S mingw-w64-x86_64-gtk3 mingw-w64-x86_64-SDL2 mingw-w64-x86_64-libslirp
- Close the MSYS2 console.
- Start ucrt64.exe.
- Download the QEMU source code:
git clone https://gitlab.com/qemu-project/qemu.git
- Finally build QEMU with:
cd qemu ./configure --enable-sdl --enable-gtk --enable-slirp make
Installation
Installation is easy with the installers from https://qemu.weilnetz.de/.
Running QEMU for W32
User mode emulation is unsupported: it only works on BSD and Linux.
System emulation
All QEMU system emulation should be working (that simply means I don't know of emulations which don't work, and those which I tried, namely x86 and mips, work well).
Hardware acceleration for x86 can be enabled with the command line option --enable-whpx
.
Special W32 devices
QEMU is based on Mingw-w64, so some commonly used UNIX device names like /dev/null or /dev/zero can be used. W32 device names also work, especially names like //./PhysicalDrive0 for the first hard disk of the host (this name must be used with extreme care or you will likely crash your system).
Text which is normally printed by QEMU to the console output channels (normally known as standard output = stdout and standard error output = stderr) might be written to files called stdout.txt and stderr.txt if QEMU was linked with SDL 1.2. If you want to see QEMU's help messages or if it does not work as expected, you should look for these files in the directory where your exe file is installed.
Running QEMU for W64
Links
- Mingw-w64 Website (supports both 32 and 64 bit builds)
- http://mingw-w64.sourceforge.net/
- GLib-2.0 for MinGW
- http://www.gtk.org/download/win32.php
- http://www.gtk.org/download/win64.php