Next: Coding guidelines, Previous: About mod-gl, Up: Hacker's guide

### 3.4 Compilation tips

#### 3.4.1 Advanced ./configure options

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

- `--enable-optimize`: will turn on optimizations. This will turn on compiler options such as `-fomit-frame-pointer` but also disable some code in the program. Indeed, most of the advanced memory checking in the game - which ensures it does not leak - will be turned of. This will certainly speed up things, however, it's not recommended to turn this on until program is not stable enough so that memory leaks and other problems can be declared 'impossible'. Turn this on if you really have some speed problem, otherwise it's safer to use the full-featured 'slow' version of the game.
- `--enable-allinone`: will stuff all the internal libraries into one big executable. Very convenient for profiling. The major drawback is that you need to have all the optional libraries installed to compile all the optional modules. Another side effect is that with this option there's no more dynamic loading of binary modules, so if your platform has a strange or buggy support for `.so` files, this option can help.
- `--enable-fullstatic`: will build a totally static binary, that is using the `--static` option for `gcc` and the `-all-static` option for `libtool`. Currently broken, this option could in the future allow for building binaries that run pretty much everywhere, without requiring any dependency but a Kernel.
- `--enable-gprof`: will enable profiling informations. This will activate `--enable-allinone`, else you would only track the time spent in functions in the main `liquidwar6` executable, and exclude lots of interesting code contained in dynamic libraries.
- `--enable-gcov`: will enable coverage informations, to use with gcov and lcov. This is for developpers only. It will activate `--enable-allinone`, else there would be some link errors when opening dynamic libraries.
- `--enable-valgrind`: will enable some `CFLAGS` options which are suitable for the use of Valgrind, to track down memory leaks and other common programming errors. Use for debugging only, usually together with `--enable-allinone`.

#### 3.4.2 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.

- autoconf2.5-2.61-1-bin.tar.bz2
- autoconf-4-1-bin.tar.bz2
- autogen-5.9.2-MSYS-1.0.11-1-bin.tar.gz
- autogen-5.9.2-MSYS-1.0.11-1-dev.tar.gz
- autogen-5.9.2-MSYS-1.0.11-1-dll25.tar.gz
- automake1.10-1.10-1-bin.tar.bz2
- automake-3-1-bin.tar.bz2
- bash-3.1-MSYS-1.0.11-1.tar.bz2
- binutils-2.18.50-20080109-2.tar.gz
- bison-2.3-MSYS-1.0.11-1.tar.bz2
- coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2
- crypt-1.1-1-MSYS-1.0.11-1.tar.bz2
- csmake-3.81-MSYS-1.0.11-2.tar.bz2
- cvs-1.11.22-MSYS-1.0.11-1-bin.tar.gz
- diffutils-2.8.7-MSYS-1.0.11-1.tar.bz2
- findutils-4.3-MSYS-1.0.11-1.tar.bz2
- flex-2.5.33-MSYS-1.0.11-1.tar.bz2
- gawk-3.1.5-MSYS-1.0.11-1.tar.bz2
- gcc-core-3.4.5-20060117-3.tar.gz
- gcc-g++-3.4.5-20060117-3.tar.gz
- gcc-g77-3.4.5-20060117-3.tar.gz
- gcc-objc-3.4.5-20060117-3.tar.gz
- gdb-6.8-mingw-3.tar.bz2
- gdbm-1.8.3-MSYS-1.0.11-1.tar.bz2
- gettext-0.16.1-1-bin.tar.bz2
- gettext-0.16.1-1-dll.tar.bz2
- gettext-0.16.1-MSYS-1.0.11-1.tar.bz2
- gettext-devel-0.16.1-MSYS-1.0.11-1.tar.bz2
- inetutils-1.3.2-40-MSYS-1.0.11-2-bin.tar.gz
- libiconv-1.11-1-bin.tar.bz2
- libiconv-1.11-1-dll.tar.bz2
- libiconv-1.11-MSYS-1.0.11-1.tar.bz2
- libtool1.5-1.5.25a-1-bin.tar.bz2
- libtool1.5-1.5.25a-1-dll.tar.bz2
- libtool1.5-1.5.25a-20070701-MSYS-1.0.11-1.tar.bz2
- lndir-6.8.1.0-MSYS-1.0.11-1.tar.bz2
- lpr-1.0.1-MSYS.tar.gz
- lzma-4.43-MSYS-1.0.11-1-bin.tar.gz
- make-3.81-MSYS-1.0.11-2.tar.bz2
- mingw-runtime-3.14.tar.gz
- mingw-utils-0.3.tar.gz
- minires-1.01-1-MSYS-1.0.11-1.tar.bz2
- MSYS-1.0.11-20071204.tar.bz2
- msysCORE-1.0.11-2007.01.19-1.tar.bz2
- openssh-4.7p1-MSYS-1.0.11-1-bin.tar.gz
- openssl-0.9.8g-1-MSYS-1.0.11-2-bin.tar.gz
- openssl-0.9.8g-1-MSYS-1.0.11-2-dev.tar.gz
- openssl-0.9.8g-1-MSYS-1.0.11-2-dll098.tar.gz
- perl-5.6.1-MSYS-1.0.11-1.tar.bz2
- perl-man-5.6.1-MSYS-1.0.11-1.tar.bz2
- regex-0.12-MSYS-1.0.11-1.tar.bz2
- tar-1.19.90-MSYS-1.0.11-1-bin.tar.gz
- texinfo-4.11-MSYS-1.0.11-1.tar.bz2
- vim-7.1-MSYS-1.0.11-1-bin.tar.gz
- w32api-3.11.tar.gz
- zlib-1.2.3-MSYS-1.0.11-1.tar.bz2

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.

- pthreads-win32, untar pthreads-w32-2-8-0-release.tar.gz then `make clean GC; cp pthread.h sched.h /usr/local/include/; cp pthreadGC2.dll /usr/local/bin/; cp libpthreadGC2.a /usr/local/lib/`
- GNU MP, untar `gmp-4.2.2.tar.gz` then `./configure && make && make install`
- Guile, untar `guile-1.8.5.tar.gz`. Edit `libguile/guile.c` and insert `#undef SCM_IMPORT` just before `#include <libguile.h>`. Edit `./libguile/threads.c` and place `struct timespec { long tv_sec; long tv_nsec; };` just before `#include "libguile/_scm.h"`. Then `./configure --disable-nls --disable-rpath --disable-error-on-warning --without-threads && make && make install`. The `GUILE_LOAD_PATH` value must be correctly set for `guile-config` to work. For unknown reasons, running `guile` can throw a stack overflow error. Don't panic. See bug 2007506 on SourceForge.net for an explanation on why the Guile binary shipped with MSYS is not suitable for Liquid War 6.
- expat, untar `expat-2.0.1.tar.gz` then `./configure && make && make install`
- SQLite, untar `sqlite-amalgamation-3.5.9.tar.gz` then `./configure && make && make install`
- libpng, untar `libpng-1.2.29.tar.gz` then `./configure && make && make install`
- libjpeg, untar `jpegsrc.v6b.tar.gz` then `./configure && make && make install && make install-lib`
- libcURL, untar `curl-7.18.1.tar.gz` then `./configure --without-ssl && make && make install`
- FreeType 2, untar `freetype-2.3.5.tar.gz` then `./configure && make && make install`
- libogg, untar `libogg-1.1.3.tar.gz` then `./configure && make && make install`
- libvorbis, untar `libvorbis-1.2.0.tar.gz` then `LDFLAGS="$LDFLAGS -logg" && ./configure && make && make install`
- SDL, untar `SDL-1.2.13.tar.gz` then `./configure && make && make install`
- SDL_image, untar `SDL_image-1.2.6.tar.gz` then `./configure && make && make install`
- SDL_mixer, untar `SDL_mixer-1.2.8.tar.gz` then `./configure && make && make install`
- SDL_ttf, untar `SDL_ttf-2.0.9.tar.gz` then `./configure && make && make install`

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:\`.