Cross-compilation for windows with mingw

From AMule Project FAQ
Jump to: navigation, search

Introduction

If you know how to compile everything on Linux, there's not much new to learn.

Two things are important:

  • use the cross-compile toolchain (i.e. i486-mingw32-gcc instead of gcc and i486-mingw32-ranlib instead of ranlib)
  • use the headers and libraries for the target system

If something goes wrong, you can expect one of these two points to be the culprit. Wrong/different headers or additional libraries (like ws2_32 for sockets) are another major source of trouble.

Most software using autotools will compile using ./configure --host=i486-mingw32; other software may require further changes.


Compilation step-by-step

Installing mingw32

Arch

 pacman -S mingw32-{binutils,gcc,runtime,w32api}

Debian/Ubuntu

 aptitude install mingw32{,-binutils,-runtime}

Setting environment variables

The value for TARGET depends on mingw32, it's i486-mingw32 for arch and i586-mingw32msvc for Debian.

 export TARGET=i486-mingw32
 #export TARGET=i586-mingw32msvc

Set a directory for building aMule. These two export commands have to be once in every terminal used to execute other command blocks shown here.

 export BUILDDIR=$HOME/mingw32

Prepare build directory

 mkdir -p $BUILDDIR
 mkdir -p $BUILDDIR/tmp

Build zlib

 cd $BUILDDIR
 wget http://www.zlib.net/zlib-1.2.5.tar.gz
 tar xzf zlib-1.2.5.tar.gz
 cd zlib-1.2.5
 CC=$TARGET-gcc AR="$TARGET-ar" RANLIB=$TARGET-ranlib ./configure --prefix=$BUILDDIR/tmp --static
 make install

You have to remove the line 'cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)' from the Makefile before running make install though.

Build libiconv

 cd $BUILDDIR
 wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.13.tar.gz
 tar xzf libiconv-1.13.tar.gz
 cd libiconv-1.13
 ./configure --host=$TARGET --prefix=$BUILDDIR/tmp
 make install

Build gettext

(patch necessary)

 cd $BUILDDIR
 wget http://ftp.gnu.org/pub/gnu/gettext/gettext-0.17.tar.gz
 tar xzf gettext-0.17.tar.gz
 cd gettext-0.17
 echo "29,30d28
 < VARIABLE(rpl_optarg)
 < VARIABLE(rpl_optind)
 " | patch gettext-tools/woe32dll/gettextlib-exports.c
 ./configure --host=$TARGET --prefix=$BUILDDIR/tmp --with-libiconv-prefix=$BUILDDIR/tmp
 make install

Build wxwidgets

 cd $BUILDDIR
 wget http://prdownloads.sourceforge.net/wxwindows/wxWidgets-2.8.11.tar.bz2
 tar xjf wxWidgets-2.8.11.tar.bz2
 cd wxWidgets-2.8.11
 ./configure --host=$TARGET --prefix=$BUILDDIR/tmp --with-libiconv-prefix=$BUILDDIR/tmp --enable-unicode --disable-shared
 make install

Build cryptopp

quite some patching necessary

 cd $BUILDDIR
 wget http://cryptopp.com/cryptopp561.zip
 mkdir cryptopp
 cd cryptopp
 unzip -a ../cryptopp561.zip
 echo "69d68
 < LDFLAGS += -pthread" | patch GNUmakefile
 echo "9c9
 < RANLIB = ranlib
 ---
 > RANLIB = $TARGET-ranlib" | patch GNUmakefile
 CXX=$TARGET-g++ RANLIB=$TARGET-ranlib AR=$TARGET-ar LDLIBS=-lws2_32 make -f GNUmakefile
 PREFIX=$BUILDDIR/tmp make -f GNUmakefile install

It complains about missing .so files. No problem.

aMule

 cd $BUILDDIR
 wget http://prdownloads.sourceforge.net/amule/aMule-2.2.6.tar.bz2
 tar xjf aMule-2.2.6.tar.bz2
 cd aMule-2.2.6
 ./configure --host=$TARGET --with-zlib=$BUILDDIR/tmp --with-wx-prefix=$BUILDDIR/tmp --with-wx-config=$BUILDDIR/tmp/bin/wx-config --with-crypto-prefix=$BUILDDIR/tmp --prefix=$BUILDDIR/tmp
 make install

Copying everything together

 cd $BUILDDIR
 mkdir pkg
 cp /usr/$TARGET/bin/mingwm10.dll $BUILDDIR/pkg
 cp $BUILDDIR/tmp/lib/*.dll $BUILDDIR/pkg
 cp $BUILDDIR/tmp/bin/amule.exe $BUILDDIR/pkg

Testing

 cd $BUILDDIR/pkg
 wine amule

Stripping binaries

It significantly reduces the binary sizes, but you will loose debug information! So don't do it if you need to send crash reports to the aMule developers.

You need the cross-compile strip tool (for instance i686-mingw32-strip instead of strip).

 cd $BUILDDIR/pkg
 $TARGET-strip amule