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'd write down the steps for setting everything up on a Debian-based OS. Tested on Linux Mint 18 and Ubuntu 16.10.
$ apt install mingw-w64
This installs all the compilers and files needed to cross-compile 32 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.
This one is available in the repos:
$ 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
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
$ cd SDL2-2.0.5/ $ sudo make cross
Follow the same steps to install SDL_mixer.
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.
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 succeeds but produces 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 SDL2 program with these Makefile additions, which will use the appropriate headers, libraries, and tools to produce a 64bit Windows exe:
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
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. All my projects come with a
lib-readme/ folder with the texts for SDL, SDL_mixer, libpng, and zlib. I just copy this folder to everything I release, it's not tedious and you're doing the right thing.