www.alxm.org

Cross-compiling a2x for Windows with MinGW

I do my game development on Linux, and use MinGW to cross-compile my C framework and games for Windows. I thought I would write down the steps for setting everything up on a Debian-based OS. Tested on Linux Mint 18 and Ubuntu 16.10.

Contents

Install MinGW#

1
$ apt install mingw-w64

This installs all the compilers and files needed to cross-compile 32bit and 64bit Windows executables. Try it out:

1
2
3
4
5
6
7
8
$ whereis x86_64-w64-mingw32-gcc
x86_64-w64-mingw32-gcc: /usr/bin/x86_64-w64-mingw32-gcc

$ x86_64-w64-mingw32-gcc --version
x86_64-w64-mingw32-gcc (GCC) 5.3.1 20160211
Copyright (C) 2015 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 PARTICULAR PURPOSE.

Install Libraries#

zlib#

This one is available in the repos:

1
$ apt install libz-mingw-w64-dev

SDL and SDL_mixer#

You can build SDL 2 from source, but for convenience I usually grab the prebuilt MinGW dev libs from the official website:

You need to edit the Makefile and change CROSS_PATH := /usr/local/cross-tools to CROSS_PATH := /usr, so that it points to where MinGW is installed. Then follow the instructions in INSTALL.txt:

1
2
$ cd SDL2-2.0.5/
$ sudo make cross

Follow the same steps to install SDL_mixer.

libpng#

libpng does not provide prebuilt MinGW binaries, so we need to build them from source. It only depends on zlib which we already installed, so this will be painless.

First, download the source code from libpng.org. Check out the Automake cross-compilation page and run ./configure --help to learn exactly what these flags do.

For 32bit:

1
2
3
4
5
6
7
$ cd libpng-1.6.28/
$ ./configure --host=i686-w64-mingw32 \
              --prefix=/usr/i686-w64-mingw32 \
              CPPFLAGS=-I/usr/i686-w64-mingw32/include \
              LDFLAGS=-L/usr/i686-w64-mingw32/lib
$ make
$ sudo make install

For 64bit replace the i686 prefixes with x86_64. If you just built the 32bit version, then also run make clean beforehand, otherwise the build might succeed but produce a broken library.

1
2
3
4
5
6
7
$ cd libpng-1.6.28/
$ ./configure --host=x86_64-w64-mingw32 \
              --prefix=/usr/x86_64-w64-mingw32 \
              CPPFLAGS=-I/usr/x86_64-w64-mingw32/include \
              LDFLAGS=-L/usr/x86_64-w64-mingw32/lib
$ make
$ sudo make install

You can confirm that the library is where it should be:

1
2
3
4
5
6
7
8
$ cd /usr/i686-w64-mingw32/lib
$ ls -lh *png*
-rw-r--r-- 1 root root 881K Mar 14 12:04 libpng16.a
-rwxr-xr-x 1 root root 157K Mar 14 12:04 libpng16.dll.a
-rwxr-xr-x 1 root root  948 Mar 14 12:04 libpng16.la
lrwxrwxrwx 1 root root   10 Mar 14 12:04 libpng.a -> libpng16.a
lrwxrwxrwx 1 root root   14 Mar 14 12:04 libpng.dll.a -> libpng16.dll.a
lrwxrwxrwx 1 root root   11 Mar 14 12:04 libpng.la -> libpng16.la

Build a Test Program#

Try building your regular SDL 2 program with these GNU Makefile additions, which should use the appropriate headers, libraries, and tools to produce a 64bit Windows executable:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
MINGW_ARCH = x86_64-w64-mingw32
MINGW_BIN = /usr/$(MINGW_ARCH)/bin

LDFLAGS += \
    $(shell $(MINGW_BIN)/sdl2-config --libs) \
    -lSDL2_mixer \
    -lpng \
    -lm \

CFLAGS += \
    $(shell $(MINGW_BIN)/sdl2-config --cflags) \

PREFIX := $(MINGW_ARCH)-

export CC      := $(PREFIX)gcc
export CXX     := $(PREFIX)g++
export AS      := $(PREFIX)as
export AR      := $(PREFIX)ar
export OBJCOPY := $(PREFIX)objcopy
export READELF := $(PREFIX)readelf
export STRIP   := $(PREFIX)strip

Runtime Libraries#

You need to distribute the SDL, libpng, and zlib runtime DLLs along with your executable program, otherwise the program might not run on all users' systems. I grab known good copies from the same libsdl.org pages linked above.

Make sure to include the DLLs' readme files to comply with their licenses. I like to include a lib-readme/ folder with my Windows binary releases, that has the readme text files for SDL, SDL_mixer, libpng, and zlib.