MXE cross compiling environment

This is the development environment I currently use (formerly MinGW cross compiling environment).

Main advantage: it works in any Unix environment (almost any, Solaris has problems since current binutils doesn’t work), I’m using it under Gentoo Linux.

Difference with the Fedora tools:

  • By default is set to build static linked programs; both environments can be used one way or the other.
  • Keeps packages up to date, the Fedora environment by policy has to follow what Fedora distributes, which is not always the very latest.

First thing I do is change my environment variables so that the cross compiler tools come first.  This is a general note to remember before jumping into any building action.

My environment changes (/opt/mxe is where I installed MXE cross compiling environment):

PATH=/opt/mxe/usr/bin:$PATH
PKG_CONFIG_PATH=/opt/mxe/usr/i686-pc-mingw32/lib/pkgconfig

There are many tools that you install on your OS, they are not part of the cross compiling environment per-se, but are needed.  Things like m4, pkg-config (not really used, unlike the Fedora setup this one has its own copy inside the environment), follow the project’s instructions: requirements

From setup

Steps:

  1. Install Git if you don’t already have it (using your OS package manager, for instance, in Gentoo: emerge -av dev-vcs/git).
  2. Install the MXE (M cross environment)
      1. First time only, see how to update below:
    git clone -b stable https://github.com/mxe/mxe.git
      1. Basic tools (binutils and gcc):
    cd mxe
    make gcc
      1. Transmission’s dependencies already ported, except Qt (dependencies of dependencies are pulled automatically):
    make curl
    make libevent
    make fontconfig
    make dbus
      1. Other dependencies (none currently)

    Patch mingwtr to add large file support ‘awareness’

      1. Qt modified with debug support

    Optional: modify src/qt.mk to add debug support, and then:

    make qt

To Transmission release

Again you have a choice of using release sources or using your own mirrored repository (you’ll need Subversion installed in your OS):

svn co svn://svn.transmissionbt.com/Transmission/trunk Transmission

The following instructions are for using the repository, for the other case just substitute autogen.sh with configure, and the directory name with the corresponding version directory.

cd Transmission && ./autogen.sh --host=i686-pc-mingw32 \
 --prefix=/home/$USER/mingw/usr/i686-pc-mingw32 \
 --enable-daemon --disable-cli --without-gtk --enable-utp \
 CFLAGS="-pipe -DSTATICLIB" LIBEVENT_LIBS="-levent -lws2_32"
make
cd qt
i686-pc-mingw32-qmake qtr.pro
make release

The parameters can be changed, what I really use due to changes in Transmission, adding large file support, and just plain testing, is:

./autogen.sh --host=i686-pc-mingw32
--prefix=/home/rberber/mingw/usr/i686-pc-mingw32
--enable-daemon --disable-cli --without-gtk --enable-utp
CFLAGS="-g0 -O3 -pipe -mthreads -DSTATICLIB -D_LFS_ -DUNICODE -DFD_SETSIZE=1024"
LIBEVENT_LIBS="-levent -lws2_32"
LDFLAGS="-Wl,--enable-stdcall-fixup"
LIBS="-lpsapi -lintl"
...
cd release
upx --best --lzma transmission-qt.exe

A couple of notes: the “-D_LFS_” is not standard, I use it to add large file support while not affecting any other package (i.e. I added the guard to Gianluigi Tiesi’s changes to MinGW).  The “-DFD_SETSIZE=1024″ sets the maximum number of open files / sockets (the default is 32, which is too low and created problems in Transmission).  The same value has to be used also while building Curl (i.e. modify src/curl.mk).

The resulting executable is in the release directory.

To get the debug version you only modify the CFLAGS to use “-ggdb3 -O0″ and in qt use “make debug”.  The executable is in the debug directory.

Updates

After you set up your environment and built things once the procedure is simplified for each new version or build.

Keeping everything up to date is easy, usually a 2-step procedure.

First:

  • Development environment:
    cd mxe && git pull
  • DBUS repository (no longer needed):
    cd dbus && git pull
  • Transmission repository:
    cd Transmission && svn up

Second:

  • Environment changes: Keep an eye on what changed and rebuild only that.  For instance, if “git pull” showed a new curl.mk installed, that probably means that there is a new version of curl and you need “make curl” to build and install it.
    Even easier, just do “make qt” and, if anything changed, in Qt or its dependencies it  will be rebuild.
  • Transmission repository: Any new revision brought with “svn up” may change the relevant parts, anything in the qt, libtransmission, and third-party subdirectories.  For this case its a good idea to do “make distclean” and then start from “./autogen.sh …”, finishing with the usual build procedure.
  • Any other packages (incl. Transmission releases if you are not using the repository): The usual procedure applies (download, un-archive, cd to unarchived source, ./configure –host=i686-pc-mingw32 …, make, etc.)