Introduction
MXE (M cross environment) is a Makefile that compiles a cross compiler and cross compiles many free libraries such as SDL and Qt. Thus, it provides a nice cross compiling environment for various target platforms, which
- is designed to run on any Unix system
- is easy to adapt and to extend
- builds many free libraries in addition to the cross compiler
- can also build just a subset of the packages, and automatically builds their dependencies
- downloads all needed packages and verifies them by their checksums
- is able to update the version numbers of all packages automatically
- directly uses source packages, thus ensuring the whole build mechanism is transparent
- allows inter-package and intra-package parallel builds whenever possible
- integrates well with autotools, cmake, qmake, andhand-written makefiles
- has been in continuous development since 2007 and is used by several projects
- has pre-compiled binaries that can be used in Continuous Integration systems
Supported Toolchains
Runtime | Host Triplet | Packages | |
---|---|---|---|
Static | Shared | ||
MinGW-w64 | i686-w64-mingw32 | 99% (379/381) | 72% (273/381) |
x86_64-w64-mingw32 | 94% (360/381) | 71% (271/381) |
These numbers were last updated on December 16, 2015. See the current status for individual packages.
OpenMP (libgomp) and pthreads (winpthreads) are always available.
Experimental support for GCC with posix threads was added in November 2015.
Tutorial
Step 1: Requirements and Download
First, you should ensure that your system meets MXE'srequirements. You will almost certainly have to install some stuff.
When everything is fine, download the current version:
git clone https://github.com/mxe/mxe.git
If you don't mind installing it in your home directory, just skip the following step and go straight to step 3.
MXE builds and installs everything under the same top-level directory and is not relocatable after the first packages are built.
Due to limitations of GNU Make, the path of MXE is not allowed to contain any whitespace characters.
Step 2: System-wide Installation (optional)
Now you should save any previous installation of the MXE. Assuming you've installed it under /opt/mxe (any other directory will do as well), you should execute the following commands:
su mv /opt/mxe /opt/mxe.old exit
Then you need to transfer the entire directory to its definitive location. We will assume again you use /opt/mxe, but feel free to use any other directory if you like.
su mv mxe /opt/mxe exit
We're almost done. Just change to your newly created directory and get going:
cd /opt/mxe
Step 3a: Build MXE
Enter the directory where you've downloaded MXE. Now it depends on what you actually want – or need.
If you choose to enter:
make
you're in for a long wait, because it compiles a lot of packages. On the other hand it doesn't require any intervention, so you're free to do whatever you like – like watch a movie or go for a night on the town. When it's done you'll find that you've installed a very capable Win32 cross compiler onto your system.
If you only need the most basic tools you can also use:
make gcc
and add any additional packages you need later on. You can also supply a host of packages on the command line, e.g.:
make gtk lua libidn
Targets can also be specified on the command line. By default, only i686-w64-mingw32.static is built, but you can build your toolchain(s) of choice with:
make MXE_TARGETS='x86_64-w64-mingw32.static i686-w64-mingw32.static'
or by adjusting the MXE_TARGETS
variable insettings.mk
.
You'll always end up with a consistent cross compiling environment.
If you have trouble here, please feel free to contact the mxe team through the issue tracker or mailing list.
After you're done it just needs a little post-installation.
Step 3b: Install MXE from the binary distribution
Instead of building MXE packages from source, you can download precompiled packages. There are two options: tar archives and Debian packages. See pkg.mxe.cc.
Step 4: Environment Variables
Edit your .bashrc script in order to change $PATH:
export PATH=/where MXE is installed/usr/bin:$PATH
You may be tempted to also add $(TARGET)/bin
to your path. You never want to do this, the executables and scripts in there will cause conflicts with your native toolchain.
In case you are using custom $PKG_CONFIG_PATH entries, you can add separate entries for cross builds:
export PKG_CONFIG_PATH="entries for native builds"
export PKG_CONFIG_PATH_i686_w64_mingw32_static="entries for MXE builds"
Remember to use i686-w64-mingw32.static-pkg-config instead of pkg-config for cross builds. The Autotools do that automatically for you.
Note that any other compiler related environment variables (like $CC, $LDFLAGS, etc.) may spoil your compiling pleasure, so be sure to delete or disable those.
For the most isolated and repeatable environment, use a white-list approach:
unset `env | \ grep -vi '^EDITOR=\|^HOME=\|^LANG=\|MXE\|^PATH=' | \ grep -vi 'PKG_CONFIG\|PROXY\|^PS1=\|^TERM=' | \ cut -d '=' -f1 | tr '\n' ' '`
Congratulations! You're ready to cross compile anything you like.
Step 5a: Cross compile your Project (Autotools)
If you use the Autotools, all you have to do is:
./configure --host=i686-w64-mingw32.static make
If you build a library, you might also want to enforce a static build:
./configure --host=i686-w64-mingw32.static --enable-static --disable-shared make
Don't worry about a warning like this:
configure: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used.
Everything will be just fine.
Step 5b: Cross compile your Project (CMake)
If you have a CMake project, you can use the provided cmake wrapper:
i686-w64-mingw32.static-cmake ...
This will automatically use the MXE version of cmake and locate the toolchain file.
Step 5c: Cross compile your Project (Qt)
If you have a Qt application, all you have to do is:
/where MXE is installed/usr/i686-w64-mingw32.static/qt/bin/qmake make
Note that Qt 4 is in the "qt" subdirectory. Qt 5 is in the "qt5" subdirectory and its qmake can be invoked similarly.
If you are using Qt plugins such as the svg or ico image handlers, you should also have a look at the Qt documentation about static plugins.
Note the sql drivers (-qt-sql-*) and the image handlers for jpeg, tiff, gif and mng are built-in, not plugins.
Step 5d: Cross compile your Project (Makefile)
If you have a handwritten Makefile, you probably will have to make a few adjustments to it:
CC=$(CROSS)gcc LD=$(CROSS)ld AR=$(CROSS)ar PKG_CONFIG=$(CROSS)pkg-config
You may have to add a few others, depending on your project.
Then, all you have to do is:
make CROSS=i686-w64-mingw32.static-
That's it!
Step 5e: Cross compile your Project (OSG)
Using static OpenSceneGraph libraries requires a few changes to your source. The graphics subsystem and all plugins required by your application must be referenced explicitly. Use a code block like the following:
#ifdef OSG_LIBRARY_STATIC USE_GRAPHICSWINDOW() USE_OSGPLUGIN(<plugin1>) USE_OSGPLUGIN(<plugin2>) ... #endif
Look at examples/osgstaticviewer/osgstaticviewer.cpp
in the OpenSceneGraph source distribution for an example. This example can be compiled with the following command:
i686-w64-mingw32.static-g++ \ -o osgstaticviewer.exe examples/osgstaticviewer/osgstaticviewer.cpp \ `i686-w64-mingw32.static-pkg-config --cflags openscenegraph-osgViewer openscenegraph-osgPlugins` \ `i686-w64-mingw32.static-pkg-config --libs openscenegraph-osgViewer openscenegraph-osgPlugins`
The i686-w64-mingw32.static-pkg-config
command from MXE will automatically add -DOSG_LIBRARY_STATIC
to your compiler flags.
Further Steps
If you need further assistance, feel free to join themailing list where you'll get in touch with the MXE developers and other users.
Download
To obtain the current version, run:
git clone https://github.com/mxe/mxe.git
To retrieve updates, run:
git pull
You can also browse the web repository.
In addition, feel free to join the mailing list and topropose new packages.