Note: I gave up and am using the popularly distributed binaries on each platform. Download Levinux and witness Linux server running with a double-click with no install from a Mac, Windows or Linux desktop. I’ll get back to compiling the binaries when some real minimal kernel and QEMU gurus interested in my project contact me.
Two down, one to go—I’ve compiled and have running successfully QEMU on Linux and Mac. Only compiling QEMU for Windows remains, and it’s time to start learning about the GNU C compiler toolchain on Windows. Yuck.
I always say that Unix is the generic plumbing of information technology, and Windows is actually among the last remaining major platforms that remains proprietary hasn’t fallen into line. Android and iOS are Linux/Unix, as are Macs, which helps explain why compiling QEMU went so easily. Only a free and open source package manager and a C library were missing.
But Windows PCs are a different animal all together. That “generic plumbing” aspect of Unix has a name. It’s called POSIX-compliance—just another standard akin to ISO and ANSII, but a a portable OS specification from the IEEE organization. Macs are in fact POSIX-compliant. While Linux isn’t technically POSIX-compliant, it’s close enough to be compatible. When you say something is Unix-like, it’s saying it’s close to that portable operating system ideal.
Windows is pretty much the other extreme. And there’s enough people who need that generic Unix-like environment even on Windows, that something called Cygwin was developed for exactly that purpose by Cygnus Systems, which is now part of Red Hat. Cygwin, which is still free and open source, lets Windows emulate a POSIX computer using a library, a compiler toolchain, and a bunch of standard ported system commands. Cygwin is what you inevitably discover when researching how to compile Unix software on Windows—but it’s got an inherent problem.
Cygwin installs on the Windows host, turning it into a Unix clone. That means there’s an emulation layer—mostly amounting to the cygwin1.dll file. Unix software compiled for Windows under Cygwin is really compiled for Cygwin and its library not Windows directly. In truth, cygwin1.dll is just another dependency that could be encapsulated and dragged around with your portable compiled software—but it’s quite a lot of overhead to carry around providing full POSIX computer emulation for your tiny little stand-alone program. It’s not a minimalist approach.
It turns out this bothered other people as well, and so now an alternative minimalist GNU C compiler package for Windows called MinGW—minimalist GNU for Windows, of course. It’s essentially just the GNU compiler toolchain—so little that there’s no comfortable place to execute commands from (you can’t expect a Unix-lover to endure DOS, can you?). So, there’s also MSYS that provides a minimal Unix-like Bourne Shell and enough commands to retrieve, make and install software.
MinGW compiles directly for a Windows dynamic link library called Msvcrt.dll, the Microsoft Visual C standard library—the thing that came before .NET and continues to be shipped with all Windows since 2000. Bottom-line, things compiled with MinGW have less dependencies and are more portable between Windows platforms, which is perfect for my QEMU project.
As of QEMU version 1.0, MinGW apparently now provides the required gcc compiler, and reportedly won’t work with the Cygwin one, so the discussion is moot anyway—except maybe valuable as research, since my last Windows PC is a seldom-used laptop at the office, and I’m at home right now, figuring out what my approach will be once I get into the office. Obviously, I’m going to have to install at least MinGW and MSYS. I’ll avoid Cygwin.
Then, I’ll have to make sure QEMU’s other dependencies are installed. On Linux and Mac, this pretty much amounted to the C standard library. I experimented a bit with getting the pre-compiled binaries for the dependencies from the GTK+ project, then I experimented a bit with compiling them from source. Finally, I followed the instructions very precisely from http://wiki.qemu.org/Hosts/W32 especially considering you can’t use just any version glib.
Okay, I’m at work on Monday morning, and let’s jump in headfirst and install MinGW and MSYS to see what that’s all about. There’s always a chicken-and-egg problem when you’re talking about toolchains for compiling. So it’s nice, particularly on Windows, when you find that you can install the toolchain with a stand-alone installer (no extra dependencies required for an install). 648 KB install that runs an installer. The installer tells me I’ll install MinGW-Get version 0.5-beta-20120426-1. You have to love a crystal-clear version numbering system!
Okay, it turns out there are repository catalogues. MinGW has a repository system like Debian. The installer asks if you want to use the pre-packeged or download the latest repository catalogues. I’m getting the latest. There’s an important screen during the install, where it asks you what compilers you want, and whether you want the MSYS Basic System and the MinGW Developer Toolkit. I’m going to just choose MSYS. A cnd.exe window pops up and does all the repository stuff. At the very end, it opens a potentially useful installation log file.
I chose all the default options, but added C++ to the languages to support (the default was just C). Okay, it’s not immediately obvious after the install where to go or what to do. I found MinGW in the Start bar, but not MSYS. There is a MinGW Shell option, so I’m opening that. When I do pwd, I see:
…so MinGW must set up directories that more-or-less mimic Unix hierarchy so that software installs into expected locations. I don’t really understand where that maps to in the Windows file system yet, but I do a couple of test commands to get the make and gcc versons, from the MinGW Shell…
$ make -v
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
This program built for i686-pc-msys
$ gcc -v
Using built-in specs.
Configured with: ../gcc-4.7.0/configure –enable-languages=c,c++,ada,fortran,obj
c,obj-c++ –disable-sjlj-exceptions –with-dwarf2 –enable-shared –enable-libgo
mp –disable-win32-registry –enable-libstdcxx-debug –disable-build-poststage1-
with-cxx –enable-version-specific-runtime-libs –build=mingw32 –prefix=/mingw
Thread model: win32
gcc version 4.7.0 (GCC)
Okay, it’s looking good. I should be able to untarball QEMU 1.2.0 into a directory and try doing a ./configure –target-list=i386-softmmu on it. How to jumnp in head first? Well, I finallyn found /home/username in:
…so, I untarballed QEMU into there and confirmed I could see it from MinGW Shell. I cd’ed into the dir, and typed:
$ ./configure –target-list=i386-softmmu
Python not found. Use –python=/path/to/python
Ugh! There’s an unexpected dependency. The good news is the ./configure actually attempted. I’ve got a toolchain! But regarding fulfilling all the dependencies I’m going to encounter now—now that I have something with its own repository, that SHOULD be my first place to look now for installs, but Python has such an official distribution point with its own Windows installer, I’m going to use that one. So, I’m installing Python 2.7.3 X86-64 MSI Installer. I’m taking all the defaults in the installer. I then had to set the path to Python with:
At this point, there’s a whole bunch of conflicting information on the net about the best route. I tried a bunch of them. But eventually, I got it to work just getting the downloads from this page http://wiki.qemu.org/Hosts/W32 and copying them directly into location in the MinGW file hierarchy. That is, no compiles or installs. Just drag things into their corresponding directories under the MinGW directory.
Okay, my first successful compile, which happens to install in c:\Program Files\QEMU, would only start qemu-system-i386 into VNC-mode, where you don’t see anything when you run QEMU. It expects you to connect with a VNC remote desktop client. It turns out, I had neither the SDL or the curses dependencies installed. It compiled anyway, because neither SDL or curses are really required. So, I tried configuring with those features enabled, and it tells me that it can’t. So I install SDL and pdcurses (a public domain version of curses recommended for Windows)—which in itself was no small chore, and that’s when things really start going wrong.
None of the QEMU make’s would succeed with the “–enable-curses” configure param when I was using pdcurses (from the repository), so I tried ncurses from source. Also no-go for different reasons. So I figured I’d try graphical SDL mode since it would compile with “–enable-SDL”, but I still only got VNC-mode. I’m missing dependencies AND am in uncharted territory. So I find a ready-made QEMU installer circa November 2011 to use as a baseline to know success is possible, but alas—it wouldn’t run with the -curses parameter! I still might be in uncharted territory.
Ugh! I don’t want to burn a second day on this project. I’m going to make a go of it this morning, then may have to put it aside for more pressing matters. I’ve tried compiling ncurses again, since I know ncurses works on the Linux and OS X installs, and PCurses I haven’t really seen work yet. And I have been totally unsuccessful. So, it’s time to investigate cross-compiling from Linux for Win32. I know I have all the dependencies on Linux that have been hanging me up on a native install on Windows. So, per http://wiki.qemu.org/Hosts/W32 from a Linux box:
apt-get install gcc-mingw32
apt-get install mingw32-binutils
Hmmmmm. It is unclear what to do next. The documentation sort of piddles out. So in further investigating cross compiling FROM Linux FOR Windows, It’s not long before one encounters http://mxe.cc/ This appears to be a project exactly for my situation: resorting to cross-compiling for Windows, but with projects that have lots of dependencies that you want to avoid spending your life hunting down. It’s got a whole bunch of free libraries that their script, a project on github, will download and build and download and build, so what you end up with is a place you can cross-compile from that has a whole grab-bag of commonly required dependencies. Oh, but their script has dependencies, and so…
And so, I’m following their advice, first getting all their Debian requirements http://mxe.cc/#requirements-debian
My first step was to apt-get install aptitude… ha ha ha!
Next, I cloned the git project:
git clone -b stable https://github.com/mxe/mxe.git
…and put it in /opt/mxe, and cd’d into the directory, and typed “make”. They say I’m in for a long wait, but it cuts down the interactions. I need all the help I can get at this point, and even if this just sets me up for success tomorrow, it is worth it. It has a trememdous list of packages that it supports http://mxe.cc/#packages including SDL and pdcurses. Even though I had bad luck with pdcurses on a native compile, I’m hopeful the problem with the int_64 datatype won’t occur when compiling on Linux.
While I’m waiting for the many downloads and compiles to finish, I’m researching exactly how a cross-compile will be different from a normal compile, and apparently all you have to do is put this as a parameter on the ./configure command:
Oh, and my last step after all the installs are done is to add to my path:
They also recommend doing a static compile if you can. I’ve had mixed luck with that with QEMU, but it appears that the configure command I’m going after is:
./configure –target-list=i386-softmmu -enable-curses –host=i686-pc-mingw32 –static
I’m also hoping that my immediately prior apt-get install of gcc-mingw32 and mingw32-binutils isn’t going to conflict with the mxe installed components I’m installing right now. I see that it does its own gcc. So, there is a question of which gcc is going to be used when I do make. But I guess that’s what editing the path is about. It will encounter /opt/mxe/usr/bin before anything else.
My desire is to complete a successful QEMU binary-for-Windows before I push out this blog post, but I think the journey and the ordeal is really enough to justify cutting it off here. Maybe someone else can step in and offer some advice.