Cross Compile to Windows From Linux

Gallagher Pryor ArrayFire, C/C++ 7 Comments

Why did I not know about this? It's like I just discovered the screw driver!

On Debian and variants (from tinc's windows cross-compilation page),


Granted, this isn't a silver bullet, but rather a quick way to get a Windows build of platform independent code that you might already have running in Linux. I've found that this approach makes it easy to get binaries out the door in a hurry when it's hard to get a project building with Visual Studio or even on the Windows platform itself (due to, say, a complex build system).

I cover some quick solutions to the most common caveats I've run into, below.


MinGW GCC vc GCC: Not as Smart with Templates

Whatever the reason, the Debian-packaged mingw flavor of gcc has a tendency to omit the instantiation of templates in many cases leading to missing symbols when linking. For instance, something like the following might sometimes complain that variants of scale can't be found on link,

A horrible (but effective) solution I've found is to push the compile along with a dead function containing references to the template instantiations that you need,

C/C++ Standard Library Dependencies

When compiling C projects, use {i686,x86_64}-w64-mingw32-gcc. The resulting binary will depend on at least KERNEL32.DLL and whatever MSVCRT.DLL is on clients' systems. Therefore, you'll need to make sure clients have the Microsoft C Runtime installed to use your software.

When compiling a C++ project, you must use {i686,x86_64}-w64-mingw32-g++ to at least link. Otherwise, you'll find you are missing LIBSTDC++-6.DLL and/or LIBGCC_S_SJLJ-1.DLL.

When shipping a C++ project, you'll need to include LIBSTDC++-6.DLL and/or LIBGCC_S_SJLJ-1.DLL with your install. You can grab these from your Linux install where you're performing the build in the associated MinGW directory, e.g., /usr/lib/gcc/x86_64-w64-mingw32/4.6/. Note that you can have gcc include these libraries statically by including the flags, -static-libgcc and -static-libstdc++.

External Dependencies

If your project depends on external libraries, you'll need them available on your Linux machine during your build. I give some quick notes for the case where you'd like to use a pre-built (mingw) windows library and specific notes for Boost.

Note that except for purely C external libraries, the libraries themselves must have been built with MinGW. The naming conventions of C++ symbols differ between MingGW and Visual Studio.

Getting a MinGW build going for each project you might want to use is different. tinc's cross compilation page gives instructions for a few libraries that it requires. You'll need to consult the documentation on a project-by-project basis for each of your dependencies.

Using a Prebuilt DLL From Windows (libpng)

LibPNG provides pre-built windows binaries (albeit ancient). To build with the library, download both the binary and developer packages and extract into the same directory. Do the same for zlib since LibPNG depends on it, as well.

To build, give the compiler access to the appropriate include directories and link to the seemingly static .dll.a files. Do not attempt to link to the .dll files. Recall that linking to DLL's on Windows requires a .lib file at build-time; by convention (at least for GNU projects), these are named with a .dll.a extension,

MinGW and Boost

I give notes on Boost, here, as it's a popular library and - since much of it is header-based - does not require a build before use in many instances.

If on Debian, you'll need a fresh copy of Boost. When building with Debian's stock version of Boost, MinGW complains of missing headers. Once you've obtained Boost, you're ready to go,