The lazy programmer scripts
scripts that work

Lazy build qemu-img.exe statically from source GitHub

qemu-img is a great tool to convert and create disk images on the fly on Windows or Linux. On Windows, I use it to convert VHD(X) to qcow2 or any disk formats you can imagine.

If you want the qemu binaries prebuilt for Windows, you can easily download them from The installer contains the qemu-img.exe binary too.

The documentation to build it on *nix systems is pretty good, but it is lacking parts of it on how to build it on Windows, especially how to build the static version of it. The official documentation can be found at

Static build means that I only want a qemu-img.exe binary which works without any open source dependency .dll. Just a small binary, preferably as small as possible (less than 5MB), which works on any Windows version > Windows Vista. The only requirement for the box where you run it is the MSVC (Microsoft Visual C++) runtime.

So, let's get the party started! The scripts below should be run in the mingw64 console after you install msys64.


# Install msys64
# You can download latest msys64 from
# - does not work anymore
# use
# and install it.
# Or you can automate msys64 installation using chocolatey
# choco install msys2 --params "/NoUpdate /InstallDir:C:\msys64" -y

# Run mingw64.exe from msys64 install folder

# Make sure pacman uses latest repos
pacman -Syy

# Install base prerequisites
pacman -S --noconfirm base-devel \
    mingw-w64-x86_64-toolchain \
    git python
# Now grab a cup or two of coffee (it takes a while)
# After this step, you might be required to
# close mingw64.exe and reopen it

# Install qemu prerequisites
pacman -S --noconfirm \
    mingw-w64-x86_64-glib2 \
    mingw64/mingw-w64-x86_64-gtk3 \

# Clone qemu repo
git clone git://

# Build qemu tools statically for Windows
cd qemu

# Now you need to apply some magic patches

# Some libraries are needed to be added for the static
# build to succeed: intl and iconv
sed -i -e 's/LIBS="-lwinmm -lws2_32 -liphlpapi $LIBS"/LIBS="-lwinmm -lws2_32 -liphlpapi -lintl -liconv $LIBS"/g' configure

# Capstone is broken, it needs to be disabled

# Guest agent should be disabled, as it cannot be built
# without extra patching:
# sed -i -e 's/  libs_qga="-lws2_32 -lwinmm -lpowrprof -lwtsapi32 -lwininet -liphlpapi -lnetapi32 $libs_qga"/  libs_qga="-lws2_32 -lwinmm -lpowrprof -lwtsapi32 -lwininet -liphlpapi -lnetapi32 -lintl -liconv $libs_qga"/g' configure

# Using --enable-debug flag makes the binary smaller :|
# Also, if we hardcode -g0 and use --enable-debug, our binary
# will have a very small size, around 5MB
sed -i -e 's/CFLAGS="-g $CFLAGS"/CFLAGS="-g0 $CFLAGS"/g' configure
sed -i -e 's/LDFLAGS="-g $LDFLAGS"/LDFLAGS="-g0 $LDFLAGS"/g' configure

# Further binary size optimizations can be done using upx
#, leading to a qemu-img.exe size of
# around 2.5MB :). Yay!

./configure --disable-user --disable-system --enable-tools \
    --disable-capstone --disable-guest-agent --enable-debug \
make -j4
# Grab another cup of coffee

# Et voila! You should have the qemu-utils binaries
ls -s1h *.exe
# 2.8M qemu-edid.exe
# 5.3M qemu-img.exe
# 5.3M qemu-io.exe

That's all, folks!

Written by kami on Friday September 27, 2019
Permalink - Tags: windows, qemu, gnu, linux, c, static

Leave a comment

comments powered by Disqus

« Lazy disable Windows 10 first logon animation - Lazy optimize running Linux from USB stick »