C/C++ Development for Windows Sans Windows



An open source development environment is preferred by many developers because of its powerful and effective tools. Additionally, it is desireable to avoid the expense of compiler licenses, proprietary operating systems, and hardware when possible. In the age of cloud-based testing and deployment, the ability to work from an open source, Linux stack means services like Travis-CI, etc can be leveraged.

In this post, we will walk through the steps to build and test C/C++-based code (ITK) for Windows from Linux or Mac OSX. This requires current ITK Git master, to be released in 4.8.0, and current CMake Git master, to be released in 3.3.0. By the end of the post, we will be able to easily build and test Windows executables from a completely open source stack.


Get the Cross-Compiler

The MXE project provides access to the GCC-based MinGW compiler for Windows. It even includes a CMake toolchain file, the configuration file that tells CMake all the information it needs to know about a cross-compiler. First, clone the MXE repository:

cd ~/src
git clone https://github.com/mxe/mxe.git
cd mxe

Next, make sure we have all the build dependencies for MXE. A typical Linux development system will already have the dependencies installed. Some dependencies may need to be installed on OSX. On Debian, for example:

apt-get install \
  autoconf automake autopoint bash bison bzip2 cmake flex gettext \
  git g++ gperf intltool libffi-dev libtool-bin libltdl-dev \
  libssl-dev libxml-parser-perl make openssl patch perl \
  pkg-config python ruby scons sed unzip wget xz-utils

After the dependencies are installed, optionally tell MXE what we want to build by default and how we want to build it. This is specified with options in a settings.mk file. We instruct MXE to build a compiler for both 32-bit and 64-bit Windows. To build faster, we can set the number of parallel jobs to the number of cores on our build host. Lastly, MXE can cross-compile a number of packages, but we will just build the cross-compiler itself by default:

cat << EOF > settings.mk
MXE_TARGETS := x86_64-w64-mingw32.static i686-w64-mingw32.static
JOBS := 8
.DEFAULT local-pkg-list:
local-pkg-list: $(LOCAL_PKG_LIST)

Build it!:



Get the Emulator

We will use an emulator to find information about the target system and test our executables. Even though the WINE project's name stands for Wine is Not an Emulator, we can utilize this fantastic, mature tool to emulate Windows. Install it on Debian with:

apt-get install wine


Build and Test

To download ITK and create a build directory:

cd ~/src/
git clone http://itk.org/ITK.git
cd ~/bin
mkdir ITK-MXE32
cd ITK-MXE32

To build and test ITK for 32-bit Windows:

cmake -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_TOOLCHAIN_FILE=~/src/mxe/usr/i686-w64-mingw32.static/share/cmake/mxe-conf.cmake \
ctest -j8 -D Experimental

The CMAKE_TOOLCHAIN_FILE variable tells CMake about the cross-compiler toolchain we want to use. The CMAKE_CROSSCOMPILING_EMULATOR variables tells CMake what command can be used to emulate the target system. The ctest command will build and test our software and upload the results to CDash so we can visualize the results.

CDash provides an overview of build errors, warnings, and which tests are passing and failing. Here we see that most tests pass with a few more failing when built for Windows 64.


What's Next

In this post we went through the steps to develop for 32-bit or 64-bit Windows from an x86_64 Linux host. We demonstrated how both build executables and obtain testing results by only specifying two variables in our CMake configuration, CMAKE_TOOLCHAIN_FILE and CMAKE_CROSSCOMPILING_EMULATOR. The reliability of these testing results depend on the quality of the target system emulator, but the presence of testing results on a dashboard is a big step towards better cross-compilation development.

In upcoming posts, we'll show how to use the same system to develop ITK-based applications for targets like Javascript for the web browser or NodeJS and Android.



3 Responses to C/C++ Development for Windows Sans Windows

  1. Theuns Heydenrych says:

    Thanks for the good article.
    How would I change the MinGW version used in the build environment mxe? Like using the latest MinGW version with posix threading and dwarf exception handling, that is available from sourceforge?

  2. Matt McCormick says:

    Hi Theuns,

    To use a different version of MinGW, create the appropriate CMake toolchain file [1] that points to the version of MinGW desired. You could start with the MXE toolchain file as a starting point. A few points of note:

    MXE is currently based of MinGW-w64 [2], which is a more actively maintained fork of MinGW that provides both 32-bit and 64-bit cross compilers.

    Dwarf-2 exception handling does not work under 64-bit Windows applications [3].

    Posix threading is slower than the Windows threads [4].

    [1] http://www.cmake.org/cmake/help/git-master/manual/cmake-toolchains.7.html

    [2] http://mingw-w64.org/doku.php

    [3] http://sourceforge.net/p/mingw-w64/wiki2/Exception%20Handling/

    [4] https://github.com/mxe/mxe/issues/431

  3. Galina Bas says:

    Hi. Thanks for your post. Really useful. Right now I’m working on a C++ programming contest. I thought it may be interesting for you. It’s about to discover Sprout SDK and try to win a Sprout computer. Here is the website sprout.coderpower.com. Would be great to have your feedback. Cheers

Questions or comments are always welcome!