Portable QEMU on macOS

The official instructions for QEMU on macOS suggest installing it system-wide with Homebrew or MacPorts. However, it's harder to build a portable version that can be moved anywhere and works on a vanilla system. On this page, I document the steps to do this.


Prerequisites

All that's needed to start is a fairly recent macOS with the command line tools installed. (I tested this on Mojave with the Xcode 10 tools.)


Steps

Make Folders

Make the output folders and set paths so we can find them later.

cd ~/Desktop
mkdir QEMU
cd QEMU

mkdir Root
export ROOT="$(pwd)/Root"

export PATH+=:"$ROOT/bin"
export CFLAGS="-I$ROOT/include"
export LDFLAGS="-L$ROOT/lib"

Download Everything

Download and unzip QEMU and its dependencies. Also, rename everything to friendlier names. (The QEMU curl and mv commands will need to be changed for new releases, of course.)

curl -L https://pkg-config.freedesktop.org/releases/pkg-config-0.29.2.tar.gz -o pkgconfig.gz
curl -L https://ftp.gnu.org/pub/gnu/gettext/gettext-0.19.8.tar.gz -o gettext.gz
curl -L https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.15.tar.gz -o libiconv.gz
curl -L ftp://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz -o libffi.gz
curl -L https://ftp.gnome.org/pub/gnome/sources/glib/2.40/glib-2.40.2.tar.xz -o glib.xz
curl -L https://www.cairographics.org/releases/pixman-0.38.0.tar.gz -o pixman.gz
curl -L https://download.qemu.org/qemu-3.1.0.tar.xz -o qemu.xz

tar -xf pkgconfig.gz
tar -xf gettext.gz
tar -xf libiconv.gz
tar -xf libffi.gz
tar -xf pixman.gz
tar -xf glib.xz
tar -xf qemu.xz

mv pkg-config-0.29.2 pkgconfig
mv gettext-0.19.8 gettext
mv libiconv-1.15 libiconv
mv libffi-3.2.1 libffi
mv pixman-0.38.0 pixman
mv glib-2.40.2 glib
mv qemu-3.1.0 qemu

Compile Dependencies

Build and install QEMU's dependencies into the temporary Root folder. Order matters, since they also depend on each other!

cd pkgconfig
./configure --prefix="$ROOT" --with-internal-glib
make
make install
cd ..

cd gettext
./configure --prefix="$ROOT"
make
make install
cd ..

cd libiconv
./configure --prefix="$ROOT"
make
make install
cd ..

cd libffi
./configure --prefix="$ROOT"
make
make install
cd ..

cd glib
./configure --prefix="$ROOT" --with-libiconv=gnu
make
make install
cd ..

cd pixman
./configure --prefix="$ROOT"
make
make install
cd ..

Compile QEMU

We can now finally build QEMU since all its dependencies are ready. The paths set in the first step allow the compiler/linker to find them even though they aren't installed system-wide.

cd qemu
./configure --prefix="$ROOT" --firmwarepath=firmware
make
make install
cd ..

Copy Files to Portable Folder

Not everything that installed to the Root folder is necessary anymore, so these commands copy just what QEMU actually needs to run into a second folder called Portable.

mkdir Portable
export PORTABLE="$(pwd)/Portable"

cp "$ROOT"/bin/qemu* "$PORTABLE"

cp "$ROOT/lib/libpixman-1.0.dylib" "$PORTABLE"
cp "$ROOT/lib/libgthread-2.0.0.dylib" "$PORTABLE"
cp "$ROOT/lib/libglib-2.0.0.dylib" "$PORTABLE"
cp "$ROOT/lib/libintl.9.dylib" "$PORTABLE"

cp -R "$ROOT/share/qemu" "$PORTABLE/firmware"

Fix Linking

This step uses install_name_tool to re-link all the executables using relative rather than absolute paths. This'll let them find the libraries even if the portable folder is moved.

for FILE in $(ls -p "$PORTABLE" | grep -v /)
do
	for LIBRARY in libintl.9.dylib libglib-2.0.0.dylib libgthread-2.0.0.dylib libpixman-1.0.dylib
	do
		install_name_tool -change "$ROOT/lib/$LIBRARY" "@executable_path/$LIBRARY" "$PORTABLE/$FILE"
	done
done

Done!

The Portable folder can now be moved anywhere, and the other files can be deleted. To use any of the systems, just cd to the directory and run ./qemu-system-whatever. (Or run a QEMU system by its absolute path and use the -L flag to point it to the firmware folder.)


Downloads

For your convenience, I've also uploaded my shell script as well as a build of QEMU 3.10.
Download Build Script
Download Portable QEMU 3.10


Alternatives

Precompiled portable builds can also be downloaded from some other sources.
Emaculation (qemu-system-ppc only)
QEMU Wiki (very old versions)