Howto: cross-compiling tinc for Windows under Linux using MinGW
This howto describes how to create a 64-bit Windows binary of tinc. Although it is possible to compile tinc under Windows itself, cross-compiling it under Linux is much faster. It is also much easier to get all the dependencies in a modern distribution. Therefore, this howto deals with cross-compiling tinc with MinGW under Linux on a Debian distribution.
Overview
The idea is simple:
- Install 64-bit MinGW.
- Create a directory where we will perform all cross-compilations.
- Get all the necessary sources.
- Cross-compile everything.
Installing the prerequisites for cross-compilation
There are only a few packages that need to be installed as root to get started:
sudo apt-get install gcc-mingw32 mingw64 git-core wget
sudo apt-get build-dep tinc
Other Linux distributions may also have 64-bit MinGW packages, use their respective
package management tools to install them. Debian installs the cross-compiler
in /usr/amd64-mingw32msvc/. Other distributions might install it in another
directory however. Check in which directory
it is installed, and replace all occurences of amd64-mingw32msvc in this
example with the correct name from your distribution.
At the time of writing, the gcc-mingw32 package contains the 64-bit compiler as well, in the future this might be put into its own package. Also, a header file is missing in the amd64-mingw32msvc include directory, a workaround is to create a symlink to the otherwise identical 32-bit version of that header file:
ln -s ../../i586-mingw32msvc/include/getopt.h /usr/amd64-mingw32msvc/include/getopt.h
Setting up the build directory and getting the sources
We will create a directory called mingw64/ in the home directory. We use
apt-get and wget to get the required libraries necessary for tinc, and use
git to get the latest development version of tinc.
mkdir $HOME/mingw64
cd $HOME/mingw64
apt-get source liblzo2-dev zlib1g-dev
wget http://www.openssl.org/source/openssl-1.0.0.tar.gz
tar xzf openssl-1.0.0.tar.gz
git clone git://tinc-vpn.org/tinc
Making cross-compilation easy
To make cross-compiling easy, we create a script called mingw64 that will set
up the necessary environment variables so configure scripts and Makefiles will
use the 64-bit MinGW version of GCC and binutils:
mkdir $HOME/bin
cat >$HOME/bin/mingw64 << EOF
#!/bin/sh
export CC=amd64-mingw32msvc-gcc
export CXX=amd64-mingw32msvc-g++
export CPP=amd64-mingw32msvc-cpp
export RANLIB=amd64-mingw32msvc-ranlib
export PATH="/usr/amd64-mingw32msvc/bin:$PATH"
exec "$@"
EOF
chmod u+x $HOME/bin/mingw64
If $HOME/bin is not already part of your $PATH, you need to add it:
export PATH="$HOME/bin:$PATH"
We use this script to call ./configure and make with the right environment
variables, but only when the ./configure script doesn’t support cross-compilation itself.
You can also run the export commands from the mingw64 script by
hand instead of calling the mingw64 script for every ./configure or make
command, or execute $HOME/bin/mingw64 $SHELL to get a shell with these
environment variables set, but in this howto we will call it explicitly every
time it is needed.
Compiling LZO
Cross-compiling LZO is easy:
cd $HOME/mingw64/lzo2-2.03
./configure --host=amd64-mingw32msvc
make
DESTDIR=$HOME/mingw64 make install
If it fails with a message about not passing the “ACC” test, create a symlink for the missing getopt.h file as mentioned above.
Compiling Zlib
Cross-compiling Zlib is also easy, but a plain make failed to compile the
tests, so we only build the static library here:
cd $HOME/mingw64/zlib-1.2.3.3.dfsg
mingw64 ./configure
mingw64 make libz.a
DESTDIR=$HOME/mingw64 mingw64 make install
Compiling OpenSSL
Although older versions will not compile, OpenSSL 1.0.0 is easy.
However, apt-get source will have applied
Debian-specific patches that break cross-compiling a Windows binary.
You need to undo those patches first.
Do not use the -j option when compiling OpenSSL, it will break.
cd $HOME/mingw64/openssl-1.0.0
quilt pop -a
mingw64 ./Configure --openssldir=$HOME/mingw64/usr/local mingw64
mingw64 make
mingw64 make install
Compiling tinc
Now that all the dependencies have been cross-compiled, we can cross-compile
tinc. Since we use a clone of the git repository here, we need to run
autoreconf first. If you want to cross-compile tinc from a released tarball,
this is not necessary.
cd $HOME/mingw64/tinc
autoreconf -fsi
./configure --host=amd64-mingw32msvc --with-openssl=$HOME/mingw64/usr/local
make
