MXE (M cross environment)

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

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:

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:

Requirements

MXE requires a recent Unix system where
all components as stated in the table below
are installed. It also needs roughly 2 GiB of
RAM to link gcc and at least 700 MB of disk
space per target (counted with only gcc
built).

Issues without a 32-bit compiler

Certain packages contain native tools that are
currently 32-bit only. In order to build these on a
64-bit system, multi-lib support must be enabled in the
compiler toolchain. However, not all operating systems
support this.

To build the remainder of MXE, specify the affected
packages to exclude:

make EXCLUDE_PKGS='ocaml%'

Usage

All build commands also download the packages if necessary.

In a BSD userland, substitute "make" with "gmake"
as all commands are based on
GNU Make.

make

build all packages,
non-parallel

make gcc

build a minimal useful set of packages,
i.e. the cross compilers
and the most basic packages,
non-parallel

so a call to make will only build those packages (and their
dependencies, of course)

make foo bar --touch

mark packages "foo" and "bar" as up-to-date after
a trivial change in one of their dependencies
(short option "-t")

make foo bar --jobs=4 JOBS=2

build packages "foo", "bar" and their dependencies,
where up to 4 packages are built in parallel
(short option "-j 4"),
each with up to 2 compiler processes running in parallel

the JOBS variable can also be defined in
settings.mk and defaults to the number
of CPUs up to a max of 6 to prevent runaway system
load with diminishing returns - see the
GNU Make manual
for more details on parallel execution

make --jobs=4 --keep-going

build all packages with 4 inter-package parallel
jobs and continue as much as possible after an error
(short option "-j 4 -k")

make EXCLUDE_PKGS='foo bar'

build all packages excluding foo, bar, and all downstream
packages that depend on them - mostly used when there are
known issues

make foo_SOURCE_TREE=/path/to/local/source

build using local source tree for package "foo", bypassing
download, checksum and patching

N.B. ensure "foo" has an out-of-source
build configured to avoid generation of build artefacts
in local tree

make check-requirements

check most of the
requirements
if necessary
– executed automatically
before building packages

make download

download all packages,
non-parallel,
such that subsequent builds work without internet access

make download-foo download-bar

download packages "foo", "bar" and their dependencies,
non-parallel

make download-foo download-bar -j 4

download packages "foo", "bar" and their dependencies,
where up to 4 packages are downloaded in parallel

Guidelines for Creating Packages

BTW, we're always curious about the applications people are porting.
We maintain a
list of projects
which use MXE.
No matter whether your project is free or proprietary
– as long as it has its own website,
we'd be happy to link to it.

Also, feel free to link to us. :-)

Grep through the src/*.mk files
to find a project that is most similar to yours.
(Really, grep is your friend here.)

For instance,
when adding a GNU library,
you should take a package like
gettext.mk
or
libiconv.mk
as the base of your work.
When using a SourceForge project,
you could start with a copy of
xmlwrapp.mk.
And so on.

Alternatively you can use tool tools/skeleton.py to
create a skeleton of new MXE package. It fills most of the fields
of .mk file automatically and supports typical
build scenarios through option --builder. It also
adds a package to the list of packages
(see below).

Adjust the comments,
fill in the $(PKG)_* fields.

To fill the $(PKG)_CHECKSUM field, use a command such as (for file gettext.mk):

make update-checksum-gettext

or:

openssl sha256 pkg/gettext-x.y.z.tar.gz

if you have already downloaded the package.

Be especially careful with the $(PKG)_DEPS section.
The easiest way to get the dependencies right
is to start with a minimal setup.
That is,
initialize MXE with make gcc only,
then check whether your package builds successfully.

Always list the dependency on gcc explicitly:

$(PKG)_DEPS := gcc ...

Things not to do:

do not run target executables with Wine, as Wine is
not guaranteed to be installed. Instead build the needed tool
natively or (if it is too huge to build one more time) add
to MXE's dependencies. This policy is forced by setting
WINEPREFIX to an empty directory, which breaks Wine;

do not download anything while building, as all files
downloaded should be verified by checksums. Instead create a
package which installs the needed file. This policy is forced
on Linux by LD_PRELOAD trick, breaking network functions.

You might also have to provide a patch for it.
In that case, have a look at other patches such as
sdl2-2-libtool.patch.
In particular, each patch file should be named as:

PACKAGE-PATCHNUMBER-DESCRIPTION.patch

and should start with:

This file is part of MXE. See LICENSE.md for licensing information.
This patch has been taken from:
https://...

where the URL points to the
bugtracker entry,
mailing list entry or
website
you took the patch from.

If you created the patch yourself,
please offer it to the upstream project first,
and point to that URL,
using the same wording:
"This patch has been taken from:".

Depending on the feedback you get from the upstream project,
you might want to improve your patch.

If you find some time,
please provide a minimal test program for it.
It should be
simple,
stand alone and
should work unmodified for many (all?) future versions of the library.
Test programs are named as:

PACKAGE-test.c

or

PACKAGE-test.cpp

depending on whether it is a C or C++ library.
To get a clue,
please have a look at existing test programs such as
sdl-test.c.

At the very end of your *.mk file
you should build the test program in a generic way,
using strict compiler flags.
The last few lines of
sdl.mk
will give you a clue.

You could also try to provide a $(PKG)_UPDATE section.
However, that requires some experience and "feeling" for it.
So it is perfectly okay if you leave a placeholder:

Check that you don't have "dirty stuff" in your *.mk files,
such as TAB characters or trailing spaces at lines endings. Run:

make cleanup-style

to remove these.
Have a look at random *.mk files
to get a feeling for the coding style.

The same holds for your test program.

However, patch files should always appear
in the same coding style as the files they are patching.

When patching sources with crlf line endings, the patch
file itself should also have the same eol style. Use the
convention of naming the file as *crlf.patch
to instruct git not to normalise the line endings (defined
in .gitattributes).

Finally, in your $(PKG)_BUILD section,
please check that you use our portability variables:

bash

→

$(SHELL)

date

→

$(DATE)

install

→

$(INSTALL)

libtool

→

$(LIBTOOL)

libtoolize

→

$(LIBTOOLIZE)

make

→

$(MAKE)

patch

→

$(PATCH)

sed

→

$(SED)

sort

→

$(SORT)

wget

→

$(WGET)

Check whether everything runs fine.
If you have some trouble,
don't hesitate to ask on the
mailing list,
providing your *.mk file so far.

Issue a
pull request
to propose your final *.mk file to us.
If you have trouble with pull requests,
send your file to the mailing list instead.

Either way,
don't forget to tell us
if there are some pieces in your *.mk file
you feel unsure about.
We'll then have a specific look at those parts,
which avoids trouble for you and us in the future.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject
to the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Legal

Disclaimer - it's all code...

Modern legal systems are like any other large, complex, and evolving body
of code you're likely to encounter.

They have their own language with quirky parsers, compilers, and
interpreters (though these tend to be human). Their issue trackers are
a backlog of court cases. They have bugs. They have traps for the
uninitiated that may potentially do more than waste your time.

We currently limit ourselves to:

--enable-languages='c,c++,objc,fortran'

so nothing mentioned here or on the mailing list should be taken as
legal advice. :-)

Choosing the right compiler

They have been very helpful in the past, and maintain an
extensive network
of legal contacts, both within and outside Europe.

Your local jurisdiction may be a signatory to various
international agreements,
so be sure to mention where you are in any correspondence (much like any
detailed bug report really).

Additionally, you should also do some background reading from the
FSF (Free Software Foundation)
and
Wikipedia
to familiarise yourself with some of the potential issues (and experience
some context-switching overhead).

Contributions

Contributions are always welcome!

Ownership of all contributions (bug fixes, new packages, doc updates, etc.)
remain with the author. All we require is a real name (no l33t handles,
please), and that you release your work under
our licence.

If you prefer not to be credited with a contribution, please notify
the committer.

Package Licences

Each package is individually licensed under terms specified by the
authors of that package. Please see the respective source tarball
and/or project website for details.

Please contact the
mailing list
if you notice a package that doesn't meet these guidlines.

Other Considerations

In addition to the usual considerations (copyrights, patents,
trademarks, export regulations etc.), building
statically linked
libraries
for Windows
exposes some edge cases that you may not have encountered before.

According to
freedom 0 and our
own licence,
you can use mxe in countless different
environments, each with it's own special legal considerations. The
configuration options of certain packages (e.g ffmpeg) allow the use of
non-free software and/or combinations that cause license violations.

For these packages, we will provide sensible defaults aimed
at achieving the following goals:

avoid causing inherent licensing issues with conflicting options

make the package as feature complete as possible

Note that this does not prevent downstream violations, or affect any
further obligations a licence may impose on you.

Unfortunately, a number of factors have forced us to drop support
for MinGW 3 (i.e. "MinGW.org"),
in favor of the MinGW-w64 toolchain. This decision was made in a
large part because of the dropping of support for MinGW by
GLib and Qt5,
which arguably are two of the most important packages in MXE.
Other considerations have also been taken, like the lack
of maintainership in MinGW and potential legal
challenges that comes with using supplemental DirectX
headers in MinGW in order to support Qt4. Worse yet, having to
support the unsupported MinGW toolchain impedes adding or
updating packages, as shown in the pull
request of updating GLib.

Please note that dropping support for MinGW DOES NOT
MEAN dropping support for the 32-bit architecture. MinGW-w64
also supports 32-bit target through i686-w64-mingw32.

To ease migration to the supported MinGW-w64 target, we have
finished porting all packages that were MinGW-only to at least
i686-w64-mingw32 (32-bit target of MinGW-w64). Hence your existing
commands should work out-of-the-box assuming the
MXE_TARGETS environment variable is set correctly.

2013-07-27 – Release 2.23

The stable branch was updated
to the current development version after a thorough
testing phase.

Current users are strongly encouraged to
start with a clean tree as the toolchain has been
updated and requires a full rebuild: