Screenshots Cross compiling 4tH: and running it:

Tutorial Step 1: Requirements and Download First, you should ensure that your system meets MXE's requirements. 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 cc 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 in settings.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 the appropriate config script (.bashrc, .cshrc, .profile, .zshrc, etc.) for your shell 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 '

' ' '` 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/qt5/bin/qmake make Note that Qt 5 is in the "qt5" subdirectory. Qt 4 is in the "qt" 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. Qt 4 only: Sql drivers (-qt-sql-*) and 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 the mailing 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 to propose new packages.

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 cc build a minimal useful set of packages, i.e. the cross compilers and the most basic packages, non-parallel make foo bar build packages "foo", "bar" and their dependencies, non-parallel the package list can also be set in settings.mk LOCAL_PKG_LIST := foo bar .DEFAULT_GOAL := local-pkg-list local-pkg-list: $(LOCAL_PKG_LIST) 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 foo bar MXE_USE_CCACHE= disables use of ccache to eliminate potential error sources when debugging 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 make download-only-foo download-only-bar download packages "foo", "bar", without their dependencies, non-parallel make clean remove all package builds – use with caution! make clean-junk remove all unused files, including unused package files, temporary folders, and logs make clean-pkg remove all unused package files, handy after a successful update make show-deps-foo print a list of upstream dependencies and all downstream dependents (direct and recursive) make show-downstream-deps-foo print a list of all recursive downstream dependents - suitable for use in shell scripts make show-direct-downstream-deps-foo print a list of direct downstream dependents - suitable for use in shell scripts make show-upstream-deps-foo print a list of upstream dependencies - suitable for use in shell scripts make docs/build-matrix.html generate a report of what packages are supported on what targets to docs/build-matrix.html make update update the version numbers of all packages, download the new versions and note their checksums make update UPDATE_DRYRUN=true show list of update candidates without downloading make update-package-foo update the version numbers of package foo, download the new version and note its checksum make check-update-package-foo check if package foo has an update available without downloading make update-checksum-foo download package foo and update its checksum make cleanup-style cleanup coding style

List of Packages See something missing? Feel free to create a new package. Loading package list...

Guidelines for Creating Packages The package should be a free software library that is really used by one of your applications. Please also review our legal notes. 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. GitHub hosted projects can automatically configure updates, urls, file names etc. by setting $(PKG)_GH_CONF instead of $(PKG)_FILE, $(PKG)_SUBDIR, $(PKG)_URL, and $(PKG)_UPDATE sections. To track releases set: $(PKG)_GH_CONF := owner/repo/releases[/latest][, tag prefix, tag suffix, tag filter-out, version separator] Releases may require setting _FILE, _SUBDIR, _URL, depending on the naming convention used by the project for tarballs. To track tags set: $(PKG)_GH_CONF := owner/repo/tags[, tag prefix, tag suffix, tag filter-out, version separator] To track branches, set: $(PKG)_GH_CONF := owner/repo/branches/<branch name> See the following packages for examples: gc.mk for release tracking with non-standard file name

yaml-cpp.mk for release tracking with standard file name

vmime.mk for branch tracking

libevent.mk for tag tracking

libffi.mk for externally hosted tarballs with generated sources not present in source tree The GNU Make Standard Library is also available (though it should be unnecessary for most packages). 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 cc only, then check whether your package builds successfully. Always list the dependency on cc explicitly: $(PKG)_DEPS := cc ... Specify official name and website of a package. If the official name coincides with the package name, you can omit $(PKG)_DESCR . PKG := libdvdetect $(PKG)_WEBSITE := https://www.dvdetect.de/ $(PKG)_DESCR := Fast database lookup for DVDs Always look for the SSL version of URLs, that is, prefer https:// URLs over http:// URLs. Write your $(PKG)_BUILD . If your library has a ./configure script, enable/disable all dependency libraries explicitly via " --enable-* " and " --disable-* " options. 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;

, 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. Useful Makefile variables provided by MXE: $(SOURCE_DIR) is a directory with package source and $(BUILD_DIR) is an empty directory intended for build files. Both directories are temporary. Prefer out-of-tree builds. Autotools and CMake support them.

$(PREFIX) is path to usr/ directory. $(TOP_DIR) is path to MXE root directory. $(TARGET) is target triplet (e.g., i686-w64-mingw32.static ). $(BUILD) is build triplet (e.g., x86_64-unknown-linux-gnu ).

$(MXE_CONFIGURE_OPTS) adds standard options to ./configure script. Typical usage: cd '$(BUILD_DIR)' && '$(SOURCE_DIR)'/configure \ $(MXE_CONFIGURE_OPTS)

$(MXE_DISABLE_CRUFT) disables installation of documentation and programs. $(MAKE) -C '$(BUILD_DIR)' -j '$(JOBS)' $(MXE_DISABLE_CRUFT) $(MAKE) -C '$(BUILD_DIR)' -j 1 install $(MXE_DISABLE_CRUFT)

$(BUILD_SHARED) is TRUE for shared targets. Useful to add flags applicable only to shared targets. $(if $(BUILD_SHARED),LDFLAGS=-no-undefined) Similarly, $(BUILD_STATIC) is TRUE for static targets; $(BUILD_NATIVE) is TRUE for native targets; $(BUILD_CROSS) is TRUE for cross targets. 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: define $(PKG)_UPDATE echo 'TODO: write update script for $(PKG).' >&2; echo $($(PKG)_VERSION) endef We'll fill that in for you. It's a funny exercise. 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.