Sunday, May 26, 2013

QEMU with MinGW... Use the source Luke

Well the law of linux applies.  As Jedi Coda said... "use the source Luke".  Well... I didn't do that... I opted for pre-complied bins and that is likely the problem.  But any any case, the problem seems to be related to me using an older tool chain.  With a good deal of help from the mailing list and lots of research, I was able to get another build working.

Originally I started with the cygwin builds, but those fell apart about the time I autotools were called.  There might be a cleaver way to merge these together, but after two days at it, I fell back to a simpler approach.  So here's what we did.  BTW... I cheated a lot, I'll eventually try a cleaner process, but here's where it was today.

1) Grab the better MinGW toolchain

Somewhere, I can't fine the reference now, it was suggested to grab one of the private builds, specifically Ruben's build.

2) Grab the better MSYS toolchain

Digging around the WIKI at I grabbed the "ultra all inclusive" MSYS build.

3) Grab the autotools package

I don't know if this is really needed, but it was convent to grab, so I did.

4) Unpack the tools (I cheated)

Now, I'm supposed to expand all of these in different directories with cleaver LIB, INCLUDE and PATH variables to get them all worked out.  After two days of fighting cygwin, I had lost most of my will to fight this good fight.  So I cheated and started hacking and slashing these toolchains.
upack mingw to c:\unpack
unpack msys to c:\unpack
unpack autotools c:\unpack\autotools
What you should see now are three directories in unpack {mingw, msys, autotools}.  Now we want to merge those directories into one directory.  Something like
cd c:\unpack
mkdir merge
move mingw32 sysroot
move sysroot merge
move msys sysroot
move sysroot merge
move autotools sysroot
move sysroot merge
Now if my memory serves me right you should have a directory {c:\unpack\merge} that should have all the stuff you want.

5) Grab gtk+ bundle and unpack

Go to the gtk+ site at and grab the bundle.  Then unpack to {c:\unpack\merge}.
get gtk+-bundle_2.24.10-20120208_win32.zipunpack to c:\unpack\merge

6) Clone ./ and ./i686-w64-mingw32 (very hackish)

There are some libraries in /lib and some in /i686-w64-mingw32/lib and resolving them got pretty gnarly.  Just for POC, I've cloned {bin, lib, include} between ./ and ./686-w64-mingw32/lib
cd c:\unpack\mergerobocopy /s .\686-w64-mingw32\bin .\binrobocopy /s .\686-w64-mingw32\lib .\librobocopy /s .\686-w64-mingw32\include .\includerobocopy /s .\bin .\686-w64-mingw32\binrobocopy /s .\lib .\686-w64-mingw32\librobocopy /s .\include .\686-w64-mingw32\include

7) Add .\lib to the Windows path and launch msys

This is required because the configure script will build and test various binaries and the DLLs have to resolve.  Once you invoke the msys shell, use that one todo all other msys work.
cd c:\unpack\mergeset PATH=c:\unpack\merge\lib;%PATH%call msys.bat{leave open you will use it in (9)}

8) Grab qemu and SDL source and unpack

We will grab the qemu and SDL source and unpack them to c:\unpack\merge\src
get qemu-1.4.1.tar.bz2unpack to c:\unpack\merge\srcget SDL-devel-1.2.15-mingw32.tar.gzunpack to c:\unpack\merge\src

9) Set the environment for the builds (hackish again)

We are using cross-compile binaries, so we need to set the compiler environment variables.  Using --host --build or --target should work for other stuff, but changing the global environment kind of catches them all.  It would be better to use --cross-prefix or something like that , but they all throw various errors.
goto the same msys windows spawned in (7)export CC=i686-w64-mingw32-gccexport CXX=i686-w64-mingw32-c++export LD=i686-w64-mingw32-ldexport AR=i686-w64-mingw32-arexport AS=i686-w64-mingw32-asexport NM=i686-w64-mingw32-nmexport STRIP=i686-w64-mingw32-stripexport RANLIB=i686-w64-mingw32-ranlibexport DLLTOOL=i686-w64-mingw32-dlltoolexport OBJDUMP=i686-w64-mingw32-objdumpexport RESCOMP=i686-w64-mingw32-windresexport WINDRES=i686-w64-mingw32-windres 

10) Build SDL and QEMU

Now we are ready to build.  Make sure you are using the same msys window from (7) and (9) since it has the environment set up.
cd /usr/src/SDL-1.2.15make nativecd /usr/src/qemu-1.4.1./configure --python=c:/Python26/python.exemakemake install

11) Test and contemplate 

So 1-10 gave us functioning binaries, but as you probably noticed, they are slow as snot.  A likely suspect is the fact that I really went to the tool chains with a meat cleaver.  Being a bit more measured will help.  Technically, I should create a clean/unhacked mingw64 / msys environment with the proper isolation and path pointers.  Then from the "clean" environment, build and install {zlib, gettext, libiconv, glib, pkg-config, SDL} from source.  Then perhaps things will work as desired.

Or it could just be that I missed some obvious ./configuration switch in (10) that would give me the normal QEMU speeds I expect.


  1. I did this work because my previous attempts to build with an older toolchain caused many access violations. The previous attempt worked if I added --enable-debug, but when I did the performance sucked. So on both cases, I can either have it fast and broken, or slow and stable.

  2. I'm going to be going through this process soon to update the Windows qemu binary for the project I have been endlessly frustrated trying to compile qemu for Windows (back during qemu 1.2), particularly a version that static links to cram as many dependencies as possible into the qemu executable, and also with text-only curses mode enabled. Thanks for your write-up. It's the most sensible one I found yet.