Cross-compiling for windows (from Linux) - Part 2
In part 1, I covered a basic
cross-compilation setup, that let us use any of the libraries that come
as part of the mingw-w64-x86-64-dev package:
Part 1:
- Install the mingw cross-compilation tools.
- Compile hello_world.exe.
- A SCons based build system, that will be used in part 2.
In this part two, I'll cover how to:
Part 2:
- Cross-compile SDL2. Cross-compile a program that links to,
and initializes SDL2.
- Repeat the process for similar libraries:
- SDL2_image, together with libjpg and libpng.
- SDL2_mixer, with libogg and libvorbis
- SDL2_ttf, with libfreetype
- GLEW
A quick word about cross-compiled libraries
Libraries used when cross-compiling also need to be cross-compiled.
For example, you probably use <cmath> functions on
Linux, and link to the shared libm.so or static
libm.a library file. For cross-compilation, you want
to link to a static cross-compiled libm.a
(shared libraries for cross-compilations
are a pita, so I'll avoid it altogether).
How do we get these static cross-compiled libraries?
Lucky for us, the mingw-w64-x86-64-dev package provides
many fundamental libraries.
On my system, these are located in /usr/x86_64-w64-mingw32/lib/.
If you find that libm.a is located there, then you can link with
it without any fuss. When building your project, it is not necessary to specify this
directory, as
x86_64-w64-mingw32-g++ will look for libraries here by default.
The important thing to note is that all the static libraries you link to
will become part of the .exe, which ends up being
a large file.
1. Building a cross-platform SDL2 library
As mentioned above, the mingw-w64-x86-64-dev package
provides many fundamental libraries. This is great, but for all other
libraries, you typically need to find these elsewhere, or build them
yourself.
I'm only interested in the latter.
First off,
Simple DirectMedia Layer (SDL).
SDL2 can be built using autotools, i.e.
configure && make && make install.
Autotools
has very good support for cross-compiling, which makes this easy.
Typically, we just need to tell configure
that we want to use the x86_64-w64-mingw32 toolchain.
I'll be placing all cross-compiled libraries we build in:
1.1 Building a cross-platform SDL2 library
In the SDL2 source repository,
we'll create a directory build-win64, and from
there call configure with the cross-compilation
configuration set. Pay attention to features the configure output
might warn you about. In my case, it all looked good, so I went
ahead with a make install.
From the SDL2 directory:
You should now find libSDL2.a and libSDL2main.a
in the $PREFIX/$TOOLSET/lib directory you used.
1.2 Hello_SDL.exe
In part 1, I described a
SCons based build setup for cross-compilation.
We want to use this to build a simple program that uses SDL2.
To check out the SCons setup, and this program, use (note the hello-sdl branch):
Here is a simple program that initializes SDL2, outputs version
information, creates a small window, and waits for the user to exit.
If you have checked out the example code, you can
build a windows execuable with scons --win64.
I won't go into much detail on how it is compiled. If it doesn't work,
and utils/windows_build.py and utils/linux_build.py
doesn't make sense, shoot me an email.
The Linux SCons build requires that sdl2-config is in the
$PATH variable. The windows build assumes that the cross-compiled
SDL2 library is in: /usr/local/cross-tools/x86_64-w64-mingw32/
The only important difference from what sdl2-config suggests
(the one corresponding to the cross-compiled SDL2),
is that I omit the -mwindows flag. With this flag set,
a console window isn't created. Although very nice for a release, I want to see
the standard output, so I won't use this flag.
Linux output
Windows output
2. Building a cross-platform SDL2_image library
We want to build a cross-platform version of SDL2_image with
jpeg and png support.
This means we have to first build libpng and libjpeg.
Also, libpng requires zlib. Will compile these
three first.
2.1 Cross-compiling zlib
Static library libz.a should now be in $CROSSPATH/lib
2.2 Cross-compiling libpng
Static library libpng.a should now be in $CROSSPATH/lib
2.3 Cross-compiling libjpeg
Static library libjpeg.a should now be in $CROSSPATH/lib
2.4 Cross-compiling SDL2_image
From the SDL2_image source directory:
Static library libSDL2_image.a should now be in $CROSSPATH/lib
2.5 Hello_SDL_image.exe
An example program with SCons build setup can be checked out with:
3. Building a cross-platform SDL2_mixer library
For the SDL2_mixer, I won't bother with .mp3 support,
since I prefer the better ogg format. For this we need both
libogg and libvorbis. I'll show how to cross-compile both.
3.1 Cross-compiling libogg
Static library libogg.a should now be in $CROSSPATH/lib
3.2 Cross-compiling libvorbis
Static library libvorbis.a and libvorbisfile.a
should now be in $CROSSPATH/lib
3.3 Cross-compiling SDL2_mixer
From the SDL2_mixer source directory:
Static library libSDL2_mixer.a should now be in $CROSSPATH/lib
3.4 Hello_SDL_mixer.exe
An example program with SCons build setup can be checked out with:
The program should list which sound and music decoders it has available.
On my Linux machine, the (relevant) output is:
On my virtual Windows7 machine:
4. Building a cross-platform SDL2_ttf library
As with previous libraries, SDL2_ttf has a dependency.
In this case, libfreetype. It also depends on libpng, but I
assume you are following this article in order, and already have that
available.
4.1 Cross-compiling libfreetype
Static library libfreetype.a should now be in $CROSSPATH/lib
4.2 Cross-compiling SDL2_ttf
From the SDL2_ttf source directory:
Static library libSDL2_ttf.a should now be in $CROSSPATH/lib
4.3 Hello_SDL_ttf.exe
An example program with SCons build setup can be checked out with:
4. Building a cross-platform GLEW library
In order to make OpenGL function calls, we use a helper library
for figuring out which functions are supported by the graphics card,
based on a system of extensions. One such helper library is GLEW.
Static library libglew32.a should now be in $CROSSPATH/lib
5. Hello_OpenGL.exe
Let's put everything together into a program
that uses and initializes SDL2,
SDL2_image, SDL2_mixer,
SDL2_ttf, and OpenGL through GLEW.
For OpenGL creation, it should try to
find the highest version that it can create a context for.
You can check out and compile this example with:
The example tries to create an OpenGL 4.4 context,
if that fails, it tries a 4.3 context,
then 4.2 and so on. After it creates an OpenGL context,
it initializes GLEW.
The version of the created context, together with graphics driver information,
extensions found, etc, are sent to the standard output.
Linux output
Windows output