Cross-Compiling Simutrans

After successfully compiling Simutrans, you may be tempted to set up a Cross-Compilation Enviroment to build Simutrans for Windows from your Linux machine. Cross-compilation of Simutrans is indeed posible and made nightly on build servers, like the bridgewater-brunellink-external server that builds Simutrans-Extended. Depending on your system, setting up the enviroment is different, but in the end, all of then will be using MinGW-w64, a cross-compilation platform, so steps for cross-compiling are the same after the set up.

Setting up the enviromentlink

For installing MinGW-w64 on a GNU/Linux machine, you generally have two options: install from your distribution repositories or install the MXE enviroment. The first option can be more difficult depending on your distribution, but will integrate better. The second option works in any distribution and it is always easy to setup, but linking dynamically will generate an enormous executable (30MB vs the usual 10MB executable), because MXE is set up in such away that all libraries are either dinamically linked or statically linked.

Installing MinGW-w64 from your distributionlink

Installing MinGW-w64 on Fedoralink

sudo dnf -y upgrade && sudo dnf -y install mingw32-nsis mingw64-pkg-config mingw64-gcc mingw64-gcc-c++ mingw64-SDL2-static mingw64-zlib-static mingw64-bzip2-static mingw64-libpng-static mingw64-winpthreads-static mingw64-freetype-static

Installing mingw64 on Arch Linuxlink

On official repositories you only have the basic toolchain.
sudo pacman -S mingw-w64 mingw-w64-pcre

For dependencies, you can install them from the AUR (they are all there) which means that they will be compiled before. If you prefer to get the binaries instead, you can add the ownstuff repositorylink-external to your /etc/pacman.conf
yay -S mingw-w64-bzip2 mingw-w64-freetype2 mingw-w64-libpng mingw-w64-miniupnpc mingw-w64-pkg-config mingw-w64-sdl2 mingw-w64-zlib mingw-w64-zstd

If you want to compile a Fluidsynth build, you can also install mingw-w64-fluidsynth from AUR, just make sure to uncomment the commented line on the PKGBUILD.

Installing MinGW-w64 from MXElink

First get the project from GitHub.
git clone https://github.com/mxe/mxe.git

cd into the directory and build the dependencies, setting MXE_TARGETS to "x86_64-w64-mingw32.static" or "x86_64-w64-mingw32.dynamic" depending on your needs.
make MXE_TARGETS='x86_64-w64-mingw32.static' bzip2 cc freetype libpng sdl2 zlib zstd

This will build all necessary dependencies. If you don't want to compile them (it will take a while), you can also download binaries from https://pkg.mxe.cc/link-external

Now you can optionally move the enviroment to a system directory
sudo mv mxe /opt/mxe


(Optional) Fix freetype linkinglink

If you are going to compile simutrans with freetype, you will need to fix librotli's static linking first. Set $MINGW_PREFIX to your own prefix (example: "/usr/x86_64-w64-mingw32").
for f in libbrotlidec libbrotlienc libbrotlicommon; do cp "$MINGW_PREFIX/lib/$f-static.a" "$MINGW_PREFIX/lib/$f.a" done

(Optional) Compiling miniupnpclink

You may have noticed that we have not compiled miniupnpc previously. This is due to miniupnpc currently shipping a broken lib, soy you have to build it yourself in your brand new enviroment. You can use the following shell script for that, which will install miniupnpc to your enviroment. You have to change accordingly the first three variables, everything else don't need any modifications.
# Change to yours. For example, for MXE static would be x86_64-w64-mingw32.static CROSS=x86_64-w64-mingw32 # Default if installed via distribution. Change to yours. MINGW_PATH=/usr/$CROSS # Default if installed via distribution. Change to yours. For example, for MXE static would be "/path/to/mxe/usr/x86_64-w64-mingw32.static/usr/bin:$PATH" PATH=/usr/$CROSS/bin:$PATH rm -rf master.zip wget https://github.com/miniupnp/miniupnp/archive/master.zip unzip -o master.zip cd miniupnp-master/miniupnpc cat Makefile.mingw | sed 's|[ \t]wingenminiupnpcstrings.exe |'"$(printf '\t')"'./wingenminiupnpcstrings.exe |' >Makefile.mingw2 $CROSS-make -f Makefile.mingw DLLWRAP=$CROSS-dllwrap CC=$CROSS-gcc AR=$CROSS-ar cp libminiupnpc.a $MINGW_PATH/lib cp *.h $MINGW_PATH/lib mkdir $MINGW_PATH/include/miniupnpc cp *.h $MINGW_PATH/include/miniupnpc cd ../.. rm -rf master.zip rm -rf miniupnp-master

(Optional) Compiling Fluidsynthlink

Optionally you may want to compile Simutrans with the Fluidsynth MIDI music backend. While it is posible to do so, you need to compile Fluidsynth manually to be linked statically, and you also need glibc installed in your mingw toolchain. You can use the following script to compile fluidsynth (change FLUIDSYNTH_VERSION and CROSS variables accordingly ).
# Change to yours. For example, for MXE static would be x86_64-w64-mingw32.static CROSS=x86_64-w64-mingw32 # Default if installed via distribution. Change to yours. MINGW_PATH=/usr/$CROSS # Default if installed via distribution. Change to yours. For example, for MXE static would be "/path/to/mxe/usr/x86_64-w64-mingw32.static/usr/bin:$PATH" PATH=/usr/$CROSS/bin:$PATH # Current Fluisynth version can be found at https://github.com/FluidSynth/fluidsynth/releases FLUIDSYNTH_VERSION=2.2.3 wget https://github.com/FluidSynth/fluidsynth/archive/v$FLUIDSYNTH_VERSION.zip unzip -o v$FLUIDSYNTH_VERSION.zip cd fluidsynth-$FLUIDSYNTH_VERSION mkdir build cd build $CROSS-cmake -DCMAKE_INSTALL_PREFIX=$MINGW_PATH -DBUILD_SHARED_LIBS=0 -Denable-aufile=0 -Denable-dbus=0 -Denable-ipv6=0 -Denable-jack=0 -Denable-ladspa=0 -Denable-midishare=0 -Denable-opensles=0 -Denable-oboe=0 -Denable-oss=0 -Denable-readline=0 -Denable-winmidi=0 -Denable-waveout=0 -Denable-libsndfile=0 -Denable-network=0 -Denable-pulseaudio=0 -Denable-dsound=1 -Denable-sdl2=0 .. $CROSS-make install cd ../.. rm -rf v$FLUIDSYNTH_VERSION.zip rm -rf fluidsynth-$FLUIDSYNTH_VERSION

Compiling Simutranslink

First. add the mingw64 bin path to your path, if not already added:
export PATH=/path/to/mingw64/bin:$PATH

This will add the path for your current terminal session.

Compiling with CMakelink

When building with CMake you need to call cmake at step 2 (generation of build files) specifying a toolchain file. Like this:
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=~/toolchain-mingw64.cmake ..

In this example the toolchain file is located at the home directory and called "toolchain-mingw64.cmake" (because it is for a 64 bit build). The content of the toolchain file is the following:

set(CMAKE_SYSTEM_NAME Windows) set(COMPILER_PREFIX x86_64-w64-mingw32-) set(CMAKE_C_COMPILER ${COMPILER_PREFIX}gcc) set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}c++) set(CMAKE_RC_COMPILER ${COMPILER_PREFIX}windres) set(CMAKE_PKGCONFIG_EXECUTABLE ${COMPILER_PREFIX}pkg-config) set(PKG_CONFIG_EXECUTABLE ${COMPILER_PREFIX}pkg-config) set(CMAKE_SYSTEM_PROCESSOR x86) set(TARGET_ENVIRONMENT /usr/x86_64-w64-mingw32/) # here is the target environment located set(CMAKE_FIND_ROOT_PATH ${TARGET_ENVIRONMENT}) # adjust the default behaviour of the FIND_XXX() commands: # search headers and libraries in the target environment, search # programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # see "Known Issues" below # link_libraries("-fstack-protector")

As always you should modify this file to suit your environment. After that, you can proceed with the usual build process.

Compiling with makelink

For compiling the game, we can set up the config.default file the same way we do for mingw on Windows. Note that calling:

autoconf && ./configure --host=x86_64-w64-mingw32.static

May result in "OSTYPE" being set incorrectly as "linux" instead of "mingw", so double check that on your config.default file. After that, add the following lines to config.default:

CC=$(CROSS)gcc CXX=$(CROSS)g++ LD=$(CROSS)ld WINDRES=$(CROSS)windres PKG_CONFIG=$(CROSS)pkg-config FREETYPE_CONFIG=$(CROSS)pkg-config freetype2 SDL2_CONFIG=$(CROSS)pkg-config sdl2

Those lines will make sure that we use the tools (gcc, g++, etc) from the cross-compiler enviroment, instead of the system tools. Now, we can finally type (adjusting CROSS value to your enviroment):
make CROSS=x86_64-w64-mingw32-

And Simutrans will compile a windows executable!

Known Issueslink

If in the linking phase you get some errors regarding freetype or other libraries with undefined references to functions like "__chk_fail", you may need to add the following to your config.default:
LDFLAGS += -fstack-protector

This is known to happen on Arch Linux, provided you installed dependencies from the AUR (2020-10).
Rate this page:

Contributors to this page: Roboron3042 .
Page last modified on Wednesday March 1, 2023 21:00:17 GMT-0000 by Roboron3042.

Online Users

7 online users

Newest Forum Posts

No records to display