Cross-compiling for Windows

From OpenTTD
Revision as of 17:32, 2 February 2017 by Pelya (Talk | contribs)

Jump to: navigation, search


Native MinGW


Should work analogously on Mac OS X, please test

You will need the MinGW binaries, includes and libraries for Linux-to-Windows cross-compiling (32-bit, 64-bit not tested) installed under /usr/i586-mingw32msvc (Debian/Ubuntu: sudo apt-get install mingw32). The further steps are more or less the same as those required for compiling with MinGW on Windows.

For consistency, self-installed libraries etc. will be stored in subfolders of /usr/local/i586-mingw32msvc. However, the OpenTTD configure script isn't very good at finding libraries that match the selected host, so some will need to be specified manually/linked to a hardcoded directory (see end).

64-bit builds

Work exactly the same way, but with all occurences of i586-mingw32msvc replaced by x86_64-w64-mingw32 (you will need 64-bit MinGW, of course - Ubuntu: mingw-w64 package). You will need to link a few files to alternative names to be able to compile with ICU after you have built ICU:

sudo ln -s <icu_sourcedir>/source/common/cmemory.h /usr/local/x86_64-w64-mingw32/include
sudo ln -s /usr/local/x86_64-w64-mingw32/lib/libsicuuc.a /usr/local/x86_64-w64-mingw32/lib/libicuuc.a
sudo ln -s /usr/local/x86_64-w64-mingw32/lib/libsicule.a /usr/local/x86_64-w64-mingw32/lib/libicule.a
sudo ln -s /usr/local/x86_64-w64-mingw32/lib/libsiculx.a /usr/local/x86_64-w64-mingw32/lib/libiculx.a

Even with these, libicui18n and libicudata still can't be found and apparently weren't even compiled? Everything does work if you leave out ICU.

List of packages

This tutorial has been tested with the following versions of the required packages:

Testing MinGW/MSYS installation

  • Open the Linux command line.
  • Run the following command:
    i586-mingw32msvc-gcc -v
  • It should output something.

Compilation and installation of the required packages

Install patch, wget, unzip and your favorite version control system if not already installed.

Compiling zlib

At the command line:

tar xvfz zlib-1.2.8.tar.gz
cd zlib-1.2.8
#  automatic replacement
sed -e s/"PREFIX ="/"PREFIX = i586-mingw32msvc-"/ -i win32/Makefile.gcc
make -f win32/Makefile.gcc 
sudo BINARY_PATH=/usr/local/i586-mingw32msvc/bin INCLUDE_PATH=/usr/local/i586-mingw32msvc/include LIBRARY_PATH=/usr/local/i586-mingw32msvc/lib make -f win32/Makefile.gcc install
cd ..

Compiling libpng

At the command line:

tar xvfJ download
cd libpng-1.5.16
./configure --host=i586-mingw32msvc --prefix=/usr/local/i586-mingw32msvc CPPFLAGS=-I/usr/local/i586-mingw32msvc/include LDFLAGS=-L/usr/local/i586-mingw32msvc/lib 
sudo make install
cd ..

Compiling liblzo2


May require a "make clean" when rebuilding

At the command line:

tar xvfz lzo-2.06.tar.gz
cd lzo-2.06
./configure --host=i586-mingw32msvc --prefix=/usr/local/i586-mingw32msvc --enable-static CPPFLAGS=-I/usr/local/i586-mingw32msvc/include LDFLAGS=-L/usr/local/i586-mingw32msvc/lib
sudo make install
cd ..

Compiling libfreetype

At the command line:

tar zxvf freetype-2.4.10.tar.gz
cd freetype-2.4.10
./configure --host=i586-mingw32msvc --prefix=/usr/local/i586-mingw32msvc --enable-static CPPFLAGS=-I/usr/local/i586-mingw32msvc/include LDFLAGS=-L/usr/local/i586-mingw32msvc/lib
sudo make install
cd ..

Compiling xz

Liblzma (which is a part of xz) is required for compiling OpenTTD since r21044. pkg-config should already be installed on your system; since it's not a library, the system versions can be used.

At the command line:

tar xvfz xz-5.0.4.tar.gz
cd xz-5.0.4
./configure --host=i586-mingw32msvc --prefix=/usr/local/i586-mingw32msvc --enable-static --disable-threads CPPFLAGS=-I/usr/local/i586-mingw32msvc/include LDFLAGS=-L/usr/local/i586-mingw32msvc/lib
sudo make install
cd ..

Compiling harbuzz

You only need harfbuzz for new version of libicu, for example 58.2.

You will need to create a symlink to libpng12.a, because libtool used by harfbuzz puts it into linked libraries:

sudo ln -s /usr/local/i586-mingw32msvc/lib/libpng.a /usr/local/i586-mingw32msvc/lib/libpng12.a 

Download and compile it:

tar xvf harfbuzz-1.4.2.tar.bz2
cd harfbuzz-1.4.2
export PKG_CONFIG_PATH=/usr/local/i586-mingw32msvc/lib/pkgconfig
./configure --host=i586-mingw32msvc --prefix=/usr/local/i586-mingw32msvc --enable-static --disable-shared --with-glib=no --with-cairo=no --with-fontconfig=no --with-icu=no
make LIBS="-lpng16 -lz"
sudo make install

Compile icu-le-hb:

cd icu-le-hb-1.0.3
export PKG_CONFIG_PATH=/usr/local/i586-mingw32msvc/lib/pkgconfig
./configure --host=i586-mingw32msvc --prefix=/usr/local/i586-mingw32msvc --enable-static --disable-shared
sudo make install

You might need to have ICU already compiled and installed without icu-le-hb first, to compile icu-le-hb.

Compiling libicu

libicu is an optional library used for handling of right-to-left scripts (e.g. Arabic and Persian) and the natural sorting of lists.

This was attempted with ICU 5.3 (newest release) after failure with the 4.6 version used in the Windows MinGW guide. The size reduction patches were not tested and probably won't work anyway.

  • Fetch and unpack the ICU source code
tar xvfz icu4c-53_1-src.tgz
cd icu
mkdir build
mkdir build-cross
  • Link the MinGW toolchain binaries to something the ICU configure script detects (really an ICU bug; you can skip this step when compiling a 64-bit version)
cd /usr/bin
for file in `ls i586-mingw32msvc-*`; do sudo ln -s $file i586-mingw32-`echo $file | rev | cut -d- -f1 | rev`; done
cd <main ICU source directory>
  • Compile ICU for your platform first, this is required to make a few build tools available
cd build
make -j<N>
cd ..
cd build-cross
# --disable-threads isn't supported anymore
../source/configure --host=i586-mingw32 --prefix=/usr/local/i586-mingw32msvc  --enable-static --disable-strict \
        CPPFLAGS=-I/usr/local/i586-mingw32msvc/include LDFLAGS=-L/usr/local/i586-mingw32msvc/lib --with-cross-build=`pwd`/../build
sudo make install
cd ..
  • You may need to copy/link the ICU header cmemory.h to an appropriate location (yet another ICU bug?):
sudo cp source/common/cmemory* /usr/local/i586-mingw32msvc/include/
  • Link the built DLLs to something icu-config detects (really an ICU bug)
cd /usr/local/i586-mingw32msvc/lib
for dll in `ls icu*.dll`; do sudo ln -s $dll lib$dll; done
  • If the build fails with error 'undefined reference to _free_locale', add parameter 'LIBS=-lmsvcr110' to 'configure' command line, this happens with ICU 58.2.

Getting the source code

Same as for standard Linux.

Compiling OpenTTD


If you are compiling for both 32 bit and 64 bit, make sure /mingw links to the correct folder for the current arch

  1. Run:
    cd ~/<path_to_source>
    # Stupid hardcoded directories; you only need to do this once
    # Note the missing slash at the end of the first argument, this is important
    sudo ln -s /usr/local/i586-mingw32msvc /mingw
    # This points pkg-config to our local mingw installation
    export PKG_CONFIG_PATH=/usr/local/i586-mingw32msvc/lib/pkgconfig
    # Also override freetype-config, icu-config etc with our own versions
    export PATH=/usr/local/i586-mingw32msvc/bin:$PATH
    # Configure, disable all libraries that are falsely detected, explicitly specify others
    ./configure --host=i586-mingw32msvc --prefix=/usr/local/i586-mingw32msvc CFLAGS="-I/usr/local/i586-mingw32msvc/include  --sysroot=/usr/i586-mingw32msvc" \ 
    LDFLAGS="-L/usr/local/i586-mingw32msvc/lib"  --without-sdl --with-lzo2=/usr/local/i586-mingw32msvc/lib/liblzo2.a

    Installing Wine and running

    wine bin/openttd.exe
    will start your Windows OpenTTD version.
Personal tools