User Tools

Site Tools


user:cavesomething:crosscompiling_for_windows

Cross Compiling for Windows

This assumes that you want to cross-compile a client for use on windows from a *nix system, and will describe the steps to do so.

This is in no way a sensible or correct way to do this, I'm merely describing an approach that works.

Parts of this are taken from http://live.gnome.org/GTK%2B/Win32/Apps which is a helpful starting point

Setup build environment

You want mingw32. If you are using a debian-like system, then the packages are mingw32, mingw32-binutils & mingw32-runtime Note that the version of mingw32-binutils that ships with lenny (2.18.50) seems to be broken, so go with the version from squeeze (or later) (ie, 2.20+)

This will install lots of starting tools in /usr/i586-mingw32msvc - if you use the equivalent packages from another distro, it may be somewhere else, just find out where, and use that whenever I refer to this location.

In order to correctly use many libraries, pkg-config is used, when compiling with mingw, it will try to run i586-mingw32msvc-pkg-config. You will need to set up an executable shell script somewhere in your path with this name. give it the following contents:

#!/bin/sh
PKG_CONFIG_LIBDIR=/usr/i586-mingw32msvc/lib/pkgconfig \
PKG_CONFIG_PATH=/usr/i586-mingw32msvc/lib/pkgconfig pkg-config $*

Get the GTK libraries

You will need the gtk libraries, fortunately there is a all-in-one bundle available from http://www.gtk.org/download-windows.html unzip this somewhere convenient.

Now, there are a number of subfolders that have just been extracted. Everything in bin should go to /usr/i586-mingw32msvc/bin Everything in lib should go to /usr/i586-mingw32msvc/lib Everything in include should go to /usr/i586-mingw32msvc/include

Everything else you can ignore.

Other Libraries

There are lots of other libraries you need, I've provided probable download locations for all of these.

At a minimum, you will need

  • pthread - you probably want to use pthreadGC2.dll
  • libpng1.2 (As distinct from 1.4 which the gtk bundle gave you) - There probably is a way to avoid this requirement, but I don't know what it is.
  • libcurl - I was using the MSVC package without SSL

Optional:

Remember to get both the developer packs and the dll files for each of these, sometimes they are in two separate downloads.

in any case:

  • dll files belong in /usr/i586-mingw32msvc/bin (and in gtk-v2/src a bit later, see below)
  • .a or .lib files belong in /usr/i586-mingw32msvc/lib
  • .h files belong in

You almost certainly will need to do some mangling of filenames, etc in order to make these all work properly, known special cases are below, but I'm sure there were others.

Special cases

SDL

If you aren't compiling with SDL support, then ignore this

sdl_config (from the sdl package) goes in bin.

Also, you will need a copy of SDL.dll in the client directory, this is because the configure script runs an SDL test program which fails if the dll isn't available.

Glut

Glut provides glut32.lib in the zip file, you will get that renamed to libglut32.a in the tidying up section below, but cf looks for -lglut, so after the tidy-up step, copy libglut32.a to libglut.a and cf will pick it up properly (there should really be a smarter way to do this)

Tidying up

some special command line voodoo:

cd /usr/i586-mingw32msvc
sed -i 's|^prefix=.*$|prefix=/usr/i586-mingw32msvc|g' lib/pkgconfig/*.pc
cd ./lib
for f in *.lib; do mv $f lib${f%%lib}a; done

After all this, be sure that you can read all of the files under /usr/i586-mingw32msvc otherwise compilation will break.

Configuring

You will need to create a configure script if you don't have one already, try running

./autogen.sh --host=i586-mingw32msvc --with-sdl-exec-prefix=/usr/i586-mingw32msvc

if you already have a configure script, then you can run it directly:

./configure --host=i586-mingw32msvc --with-sdl-exec-prefix=/usr/i586-mingw32msvc

(if you are using a different version of pthread, then change LIBS as appropriate).

either way, you should end up with a configuration summary that looks like this:

configure: Configuration summary....                                                                                          
configure:                                                                                                                    
configure:   Paths                                                                                                            
configure:     prefix default value                 /usr/local                                                                
configure:     exec_prefix default value            ${prefix}                                                                 
configure:     Will put executables in              /usr/local/bin                                                            
configure:     Will put config in                   ${prefix}/etc                                                             
configure:     Will put data in                     .                                                                         
configure:                                                                                                                    
configure:   Build options                                                                                                    
configure:     Will build GTK2 client?              yes                                                                       
configure:     With OpenGL renderer?                yes                                                                        
configure:     With SDL renderer?                   yes                                                                       
configure:     Will build sound server?             no                                                                        
configure:                                                                                                                    
configure:   Scripting options                                                                                                
configure:     Will include lua interface?          no     

If you are compiling with SDL support then the line 'With SDL renderer?' should say 'yes' If you are compiling with OpenGL support then the line 'With OpenGL renderer?' should say 'yes'

You have a Makefile now, so run make.

Compilation

You may well see errors here, bodge the source code until they go away.

At the time of writing, the SVN client compiles cleanly, as long as -DMINGW is passed when compiling gtk-v2/src/config.c

However, in order to let it link, I have needed to comment out references to gtk_rc_add_default_file and gtk_rc_set_default_files

The following is a diff if you want to apply that

Index: config.c
===================================================================
--- config.c    (revision 13271)
+++ config.c    (working copy)
@@ -210,7 +210,7 @@
      * theme change grows the list.  Only one theme should be in the list
      * at a time.
      */
-    gtk_rc_set_default_files(default_files);
+//    gtk_rc_set_default_files(default_files);

     /*
      * If a client-configured theme has been selected (something other than
@@ -232,7 +232,7 @@
             LOG(LOG_ERROR, "config.c::load_theme",
                 "Unable to find theme file %s", path);

-        gtk_rc_add_default_file(path);
+//        gtk_rc_add_default_file(path);
     }

     if (reload) {

Linking

All being well, it will compile the c code and fail dismally in the linker step.

That's ok, we didn't pass the right configure-time options to link it properly anyway.

go to gtk-v2/src and run the linker step manually, what you will need to use will depend on which compile-time options you have.

Without either SDL or OpenGL support enabled, run

i586-mingw32msvc-gcc -mwindows -g -O2 -mms-bitfields -Wall   -o crossfire-client-gtk2.exe about.o account.o config.o image.o info.o inventory.o keys.o main.o map.o magicmap.o menubar.o metaserver.o opengl.o pickup.o png.o sdl.o skills.o sound.o spells.o stats.o ../../common/libcfclient.a /usr/i586-mingw32msvc/lib/libgdk_pixbuf-2.0.dll.a /usr/i586-mingw32msvc/lib/libglade-2.0.dll.a /usr/i586-mingw32msvc/lib/libpango-1.0.dll.a /usr/i586-mingw32msvc/lib/libgtk-win32-2.0.dll.a -lpthreadGC2 -lgdk-win32-2.0 -latk-1.0 -lpangoft2-1.0 -lm -lpangocairo-1.0 -lgio-2.0 -lcairo -lfreetype -lfontconfig -llibgobject-2.0 -lgmodule-2.0 -llibglib-2.0   -lwsock32 -lwinmm -lpng12 -lz -lm  -llibcurl -lgailutil -lmingw32 -mwindows

if you are compiling with SDL, then add

-lSDL -lSDL_image -lSDLmain /usr/i586-mingw32msvc/lib/libSDL.dll.a

if you are compiling with OpenGL, then add

-lopengl32 -lglu32 -lglut

If you are doing both then you'll end up with the following

i586-mingw32msvc-gcc -mwindows -g -O2 -mms-bitfields -Wall   -o crossfire-client-gtk2.exe about.o account.o config.o image.o info.o inventory.o keys.o main.o map.o magicmap.o menubar.o metaserver.o opengl.o pickup.o png.o sdl.o skills.o sound.o spells.o stats.o ../../common/libcfclient.a /usr/i586-mingw32msvc/lib/libgdk_pixbuf-2.0.dll.a /usr/i586-mingw32msvc/lib/libglade-2.0.dll.a /usr/i586-mingw32msvc/lib/libpango-1.0.dll.a /usr/i586-mingw32msvc/lib/libgtk-win32-2.0.dll.a -lpthreadGC2 -lgdk-win32-2.0 -latk-1.0 -lpangoft2-1.0 -lm -lpangocairo-1.0 -lgio-2.0 -lcairo -lfreetype -lfontconfig -llibgobject-2.0 -lgmodule-2.0 -llibglib-2.0   -lwsock32 -lwinmm -lpng12 -lz -lm  -llibcurl -lgailutil -lSDL -lSDL_image -lmingw32 -lSDLmain -mwindows /usr/i586-mingw32msvc/lib/libSDL.dll.a -lopengl32 -lglu32 -lglut

That should give you a .exe file.

Aside

I can get:

i586-mingw32msvc-gcc -mwindows -g -O2 -mms-bitfields -Wall -o crossfire-client-gtk2.exe about.o account.o config.o image.o info.o inventory.o keys.o main.o map.o magicmap.o menubar.o metaserver.o opengl.o pickup.o png.o sdl.o skills.o sound.o spells.o stats.o ../../common/libcfclient.a -lgdk_pixbuf-2.0 -lglade-2.0.dll -lpango-1.0 -lgtk-win32-2.0 -lpthreadGC2 -lgdk-win32-2.0 -lgobject-2.0 -lglib-2.0 -lwsock32 -lwinmm -lpng12 -lcurl -lmingw32 -lSDLmain -mwindows -lSDL.dll -lopengl32

to link on my system, so you may be able to do cull some of those linker options. Note two things though:

  1. I have made substantial modifications to the layout of my usr/i586… directories, which I wasn't documenting at the time
  2. This still doesn't resemble the set of options the linker is passed by the configure script.

DLL Hell

Now grab lots of dll files from /usr/i586-mingw32msvc/bin and put them in gtk-v2/src

Start with this list:

  • libcurl.dll
  • pthreadGC2.dll
  • zlib1.dll
  • freetype6.dll
  • libexpat-1.dll
  • libglade-2.0-0.dll
  • libgtk-win32-2.0-0.dll
  • libpng12-0.dll
  • libpng14-14.dll
  • iconv.dll
  • libfontconfig-1.dll
  • libglib-2.0-0.dll
  • libpango-1.0-0.dll
  • libatk-1.0-0.dll
  • libgdk_pixbuf-2.0-0.dll
  • libgmodule-2.0-0.dll
  • libpangocairo-1.0-0.dll
  • libcairo-2.dll
  • libgdk-win32-2.0-0.dll
  • libgobject-2.0-0.dll
  • libpangoft2-1.0-0.dll
  • libgio-2.0-0.dll
  • libgthread-2.0-0.dll
  • libpangowin32-1.0-0.dll
  • libxml2.dll
  • SDL.dll (even if you didn't compile with SDL support, because the nsis script needs it, edit the nsi file if you really don't want to include it)

and add more if you need them, keep going until a windows system can actually run the binary from gtk-v2/src.

Client Images

The windows package is distributed with the client image files already included, for the unix clients, this is a separate package. download the latest crossfire-client-images-x.y.z.tar.gz file from sourceforge, and untar into gtk-v2/src, this will ensure that they are included in the package.

Making the package

Finally….

Install nsis, on a debian-like system the package is called nsis

go to gtk-v2/win32 and have a look at the file gtkclient.nsi

Near the top of the file, there is a line like this

!define PRODUCT_VERSION "1.50.0"

if you added any additional dll's beyond those listed in the linking section, then add a line like

  File "..\src\extradllIneeded-x.y-z.dll"
<code>

to the install section (where all the other dlls are being added)

and a line like
<code>
  Delete "$INSTDIR\extradllIneeded-x.y-z.dll"

to the uninstall section.

Change the version number to the version you are building.

run makensis gtkclient.nsi

You should have an installer file crossfire-client-windows.exe

This can now be installed on a windows system.

user/cavesomething/crosscompiling_for_windows.txt · Last modified: 2010/05/20 19:13 (external edit)