Next: , Previous: , Up: Hacker's guide   [Contents][Index]


3.8 Compilation tips

3.8.1 Advanced ./configure options

In addition to all the common Autoconf switches such as --prefix, Liquid War 6 has some custom switches:

3.8.2 Debian packages

Liquid War 6 does have a ./debian in both main and extra maps packages, so it’s “debianized”. To build the main .deb package, untar the main source tarball, then:

make dist
cd pkg
cp ../liquidwar6-X.Y.Z.tar.gz . # X.Y.Z is the version
make deb

Note that you have to copy the source tarball to ./pkg and move to this directory before typing make deb. This is, among other things, to simplify the main Makefile.

To build the extra maps .deb package, untar the extra maps tarball, then:

make deb

3.8.3 Red Hat packages

Liquid War 6 does have a .spec files in both main and extra maps packages. To build the main .rpm package, untar the main source tarball, then:

make dist
cd pkg
cp ../liquidwar6-X.Y.Z.tar.gz . # X.Y.Z is the version
make rpm

Note that you have to copy the source tarball to ./pkg and move to this directory before typing make rpm. This is, among other things, to simplify the main Makefile.

To build the extra maps .rpm package, untar the extra maps tarball, then:

make rpm

3.8.4 Microsoft Windows msys/mingw32 port

This section describes how to compile the game from source under Microsoft Windows. Note that players are encouraged to use a free system such as GNU/Linux, which is the platform Liquid War 6 is being hacked on by default. If you encounter problems with this port, you’ll probably save time by installing a double-boot with GNU/Linux coexisting with your previous Microsoft Windows install.

Basically, Liquid War 6 requires MinGW. More precisely, it requires MSYS. A standard Cygwin installation won’t work, because it is too UNIXish to allow third party libraries like SDL to compile natively. You might argue that SDL is available for Cygwin, but in reality, the Cygwin port of SDL is a MinGW port. Indeed, Cygwin brings all standard POSIX functions including the use of main instead of WinMain and I suspect this is a problem for graphical libraries like SDL which do require some sort of direct access to the OS low-level functions. Therefore, MinGW is more adapted for it does not define all these functions, and allows any library to hook on Microsoft Windows internals directly. Point is then, you also loose the cool effect of Cygwin which is to have a complete glibc available, including network functions like select defined the POSIX way, and not the WinSock way. If you ever ported code from POSIX sockets to WinSock 2, you know what I mean. Using MinGW is also embarassing for some libraries won’t compile easily, and for instance programs which heavily rely on a real TTY interface to work are usually hard to port. This includes ncurses and GNU readline. Liquid War 6 tries to have workarrounds for all this, and in some cases the workarround is simply that embarassing code is not compiled on Microsoft Windows. For this reason, some features are not available on this platform. Period.

Now the reason you need MSYS and not only MinGW is that MSYS will allow ./configure scripts to run, and this eases up the porting process a lot. MinGW and MSYS packages are downloadable on the SourceForge MinGW download page. Alternatively, there is a mirror on ufoot.org, but files might be outdated.

To compile Liquid War 6, first download and unzip all the following files in the same directory, for instance C:\MSYS. If you do not have any tool to handle .tar.gz and .tar.bz2 files under Microsoft Windows, which is likely to be the case when MSYS is not installed yet, you can untar these on any GNU/Linux box, then upload the whole directory to the target Windows host.

This file list might contain file which are not absolutely mandatory for Liquid War 6, for instance the Fortran 77 compiler is absolutely useless, but installing it won’t harm either. Some packages might unzip things the right way, but some do it in a subfolder. You might need to run commands like:

cp -r coreutils*/* .
rm -rf coreutils*

Get rid of useless files:

rm ._.DS_Store .DS_Store 

It’s also mandatory to move everything that has been installed in /usr or /usr/local to / since MSYS has some builtin wizardry which maps /usr on /. You need to do this if you don’t unzip files from a MinGW shell, which is obviously the case when you first install it. Usefull command can be:

mv usr/* .
rmdir usr

Next, libintl is not correctly handled/detected by LW6, and can raise an error like "gcc.exe: C:/msys/local/lib/.libs/libintl.dll.a: No such file or directory" so one needs to copy some libraries in /usr/local/lib/.libs/:

mkdir local/lib/.libs
cp local/lib/libintl.* local/lib/.libs/

Another step is to edit /etc/profile and add lines like:

export CFLAGS="-g -I/usr/local/include"
export LDFLAGS="-L/usr/local/lib"
export GUILE_LOAD_PATH="C:\\MSYS\\local\\share\\guile\\1.8\\"

Close and re-launch your msys shell (rxvt) so that these changes take effect. Check that those values are correctly set:

env | grep FLAGS
env | grep GUILE

Finally, your MSYS environment is (hopefully...) working.

Now you need to compile the following programs, from source. Files are mirrored on ufoot.org for your convenience, however these might be outdated. Still, there are known to work. Proceed like if you were under a POSIX system. Some packages use the --disable-rpath swith, there are various reasons for which rpath is an issue. In the same manner, --disable-nls when linking against libintl or libiconv was painful.

For your convenience, a zip file containing a complete MSYS "Liquid War 6 ready" environment is available. It is simply the result of all the operations described above. Simply unzip msys-for-liquidwar6-20080819.zip (about 240 megs) in C:\MSYS\. All dependencies compiled in /local have been generated using the command:

cd /usr/local/src
./msys-for-liquidwar6-build.sh > ./msys-for-liquidwar6-build.log 2>&1

Note that this script does’t do everything, you’ll still need to edit Guile source code and patch it manually.

It might even be possible to use this MSYS environment under Wine. Simply unzip it under $HOME/.wine/drive_c, and run wine "$HOME/.wine/drive_c/windows/system32/cmd.exe" /c "c:\\msys\\msys.bat" and with luck, you’ll get a working shell. Note that this might allow you to compile the game, but running it is another story. Consider this MSYS over Wine trick as a hack enabling the use of free software only when compiling for Microsoft proprietary platform. It is not a reasonnable way to run the game. If running under a UNIXish platform, or better, GNU, simply run native code. Use the Windows 32-bit port only if you are jailed on a Microsoft system.

Now, let’s come to the real meat, untar the Liquid War 6 source tarball, launch your MSYS shell, and:

./configure
make
make install

Now the binary is in src/.libs/liquidwar6.exe (beware, src/liquidwar6.exe is only a wrapper). This binary is an MSYS/MinGW binary, so it read paths “à la” Microsoft, that is, it has no knowledge of what /usr is, for instance. It requires paths starting by C:\.

3.8.5 Mac OS X port

This is still experimental. Basically, install MacPorts, and most dependencies with, except for SDL which you compile from source. The idea is to compile SDL using the native OS X bindings (and not some other GL files you could have in /opt/local installed by MacPorts), then compile the game and other SDL dependencies against this SDL.

The SDL_mixer library might need to be told to compile itself without dynamic ogg support. By default it seems that it tries to load libvorbisfile.dylib at runtime, and it can fail. To disable this dynamic loading, use for instance :

/configure --prefix=/opt/extra --enable-music-ogg --disable-music-ogg-shared 

Also, it might seem obvious for Mac OS X users, but there are some important issues related to compiling options and handling dynamic libraries at runtime.

It is very important to have the right SDL flags when linking the Liquid War 6 binaries. For instance it could be:

-I/opt/extra/include -I/opt/local/include -Wl,-framework -Wl,CoreFoundation -I/opt/local/include -D_THREAD_SAFE -Wl,-framework -Wl,Cocoa -Wl,-framework -Wl,OpenGL -Wl,-framework -Wl,Cocoa 

The point is to have Cocoa and OpenGL support. Depending on the way you installed SDL, you might also need to include an SDL framework support, this is mostly if you installed SDL from .dmg binary images, and not from source with the command line. A typical output of sdl-config --libs is:

-L/opt/extra/lib -lSDLmain -lSDL -Wl,-framework,Cocoa

Another important issue is to include SDL.h, which in turn includes SDLmain.h, in all the .c source files defining the standard main function. This is done in liquidwar6 but should you try to link yourself on liquidwar6 libraries and/or hack code, you must do this or you’ll get errors when running the game. Such errors look like:

*** _NSAutoreleaseNoPool(): Object 0x420c90 of class NSCFNumber autoreleased with no pool in place - just leaking

The reason is that SDL replaces your main with its own version of it. One strong implication is that all the dynamic loading of SDL, which works on sandard GNU/Linux boxes, won’t work under Mac OS X, since SDL hard codes itself by patching main with #define C-preprocessor commands.

A .dmg file (disk image) containing a Liquid War 6.app folder (OS X application) is available for your convenience. It might work or not. In doubt, compile from source. The complicated part about this package (a “bundle” is OS X language) is that it needs to embed various libraries which are typically installed in /opt by MacPorts on a developper’s machine. So to build this package a heavy use of the utilility install_name_tool is required, normally all libraries needed ship with the binary, remaining depedencies concern frameworks which should be present on any working Mac OS X install. Still, this is only theory. Needs to be widely tested.

The layout of the bundle follows:

Additionnally, the Mac OS X port uses /Users/<username>/Library/Application Support/Liquid War 6/ to store configuration file, logs, etc. It does not use $HOME/.liquidwar6 like the default UNIX port.

The Mac OS X port also has a special behavior, in order to load some libraries with dlopen (SDL_image does this with libpng and libjpeg) it needs to set DYLD_FALLBACK_LIBARY_PATH to a value that contains these libraries. This is typically in the bundle distributed on the disk image. On a developper’s computer this problem does not appear for those libs are often in places like:

So the program sets DYLD_FALLBACK_LIBARY_PATH (but not DYLD_LIBRARY_PATH else it breaks internal OS X stuff which relies, for instance, on libjpeg library that has the same name but different contents) but it needs to do it before it is even run, else the various dyld functions do not acknowledge the change. That is, calling the C function setenv(), even before dlopen(), has no effect. So the program calls exec() to re-run itself with the right environment variable. This is why, on Mac OS X, there are two lines (exactly the same ones) displaying the program description when it is started in a terminal.

3.8.6 GP2X port

This is not working yet, but there are good hopes that some day, Liquid War 6 can run on a GP2X console. This handled gaming device uses a Linux kernel on an ARM processor, does support most GNU packages through cross-compilation, and has basic SDL support.

To compile Liquid War 6 for GP2X, you first need to set up a working “toolchain”. It’s suggested you do this on a working GNU/Linux box. There are several solutions, the recommended one being Open2x. Read the online documentation on how to install Open2x.

Basically, the following should work:

mkdir /opt/open2x # check that you can write here
svn co https://open2x.svn.sourceforge.net/svnroot/open2x/trunk/toolchain-new open2x-toolchain 
./open2x-gp2x-apps.sh
cd open2x-toolchain

Then, for your environment to be complete, you need to set up some environment variables. For instance:

export OPEN2X_SYSTEM_PREFIX=/opt/open2x/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux
export GP2X_USER_PREFIX=$HOME/gp2x

export CC=${OPEN2X_SYSTEM_PREFIX}/bin/arm-open2x-linux-gcc
export CPP=${OPEN2X_SYSTEM_PREFIX}/bin/arm-open2x-linux-cpp
export CXX=${OPEN2X_SYSTEM_PREFIX}/bin/arm-open2x-linux-g++
export AS=${OPEN2X_SYSTEM_PREFIX}/bin/arm-open2x-linux-as

export CFLAGS=''-I${OPEN2X_PREFIX}/include -I${GP2X_USER_PREFIX}/include''
export CPPFLAGS=''-I${OPEN2X_PREFIX}/include -I${GP2X_USER_PREFIX}/include''
export CXXFLAGS=''-I${OPEN2X_PREFIX}/include -I${GP2X_USER_PREFIX}/include''
export LDFLAGS=''-L${OPEN2X_PREFIX}/lib -L${GP2X_USER_PREFIX}/lib''

export PATH=''${GP2X_USER_PREFIX}/bin:${OPEN2X_SYSTEM_PREFIX}/bin:$PATH''

In this setting, there’s a user $HOME/gp2x directory which will contain all the Liquid War 6 related libraries while the /opt/open2x remains untouched.

Then you need to install the requirements. All these packages need to be cross-compiled. To make things clear and non-ambiguous, even if you have CC set up in your environment variables, pass --build and --host arguments to the ./configure script of all these packages. A typical command is:

./configure --build=i686-pc-linux-gnu --host=arm-open2x-linux --prefix=${GP2X_USER_PREFIX}

Here’s the list of the requirements:

Next, one needs to install a special version of SDL, which targets the GP2X specifically. This is not a generic SDL, and it does have limitations, which are related to the GP2X peculiar hardware. There are installation instructions about how to do this. The following should work:

cvs -d :pserver:anonymous@cvs.sourceforge.net:/cvsroot/open2x login # blank password
cvs -d :pserver:anonymous@cvs.sourceforge.net:/cvsroot/open2x co libs-gp2x 

Next: , Previous: , Up: Hacker's guide   [Contents][Index]