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

On Debian and variants (from <a href="http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/">tinc's windows cross-compilation page</a>),
<pre style="margin-bottom: 20px;">sudo apt-get install mingw-w64

# C
i686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit
x86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit

# C++
i686-w64-mingw32-g++ hello.cc -o hello32.exe     # 32-bit
x86_64-w64-mingw32-g++ hello.cc -o hello64.exe   # 64-bit
</pre>
<img class="aligncenter" style="margin-top: 20px;" src="http://i.imgur.com/C4buo.gif" alt="blown" />

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.
<h2>Caveats</h2>
<h3>MinGW GCC vc GCC: Not as Smart with Templates</h3>
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 <code>scale</code> can't be found on link,
<pre>template <class ty> void scale(ty a, ty *X, unsigned n) {
  for (int i = 0; i < n; i++) X[i] = a * X[i];
}
void scale_ALL_the_things(float *A, int *B, unsigned n) {
  scale(2.0, A, n);
  scale(  3, B, n);
}
</pre>
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,
<pre>void __force_compile() {
  scale(0, 0, NULL);
  scale(0, 0, NULL);
}
</pre>
<h3>C/C++ Standard Library Dependencies</h3>
When compiling C projects, use <code>{i686,x86_64}-w64-mingw32-gcc</code>. The resulting binary will depend on at least <code>KERNEL32.DLL</code> and whatever <code>MSVCRT.DLL</code> 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 <b>must</b> use <code>{i686,x86_64}-w64-mingw32-g++</code> to at least link. Otherwise, you'll find you are missing <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code>.

When shipping a C++ project, you'll need to include <code>LIBSTDC++-6.DLL</code> and/or <code>LIBGCC_S_SJLJ-1.DLL</code> with your install. You can grab these from your Linux install where you're performing the build in the associated MinGW directory, e.g., <code>/usr/lib/gcc/x86_64-w64-mingw32/4.6/</code>.
<h3>External Dependencies</h3>
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 windows library and specific notes for Boost.

Getting a MinGW build going for each project you might want to use is different. <a href="http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/">tinc's cross compilation page</a> 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.
<h4>Using a Prebuilt DLL From Windows (libpng)</h4>
<a href="http://gnuwin32.sourceforge.net/packages/libpng.htm">LibPNG</a> provides pre-built windows binaries (albeit ancient). To build with the library, download <b>both</b> the binary and developer packages and extract into the same directory. Do the same for <a href="http://gnuwin32.sourceforge.net/packages/zlib.htm">zlib</a> since LibPNG depends on it, as well.

To build, give the compiler access to the appropriate <code>include</code> directories and link to the seemingly static <code>.dll.a</code> files. <b>Do not attempt to link to the <code>.dll</code> files</b>. Recall that linking to DLL's on Windows requires a <code>.lib</code> file at build-time; by convention (at least for GNU projects), these are named with a <code>.dll.a</code> extension,
<pre>i686-w64-mingw32-gcc -Ilibpng/include -Izlib/include -o pngwriter.exe pngwriter.cc -Llibpng/lib -lpng -Lzlib/lib -lz
</pre>
<h4>MinGW and Boost</h4>
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,
<pre>wget 'http://sourceforge.net/projects/boost/files/latest/download?source=files' -O boost.tar.gz
tar xzfp boost.tar.gz
x86_64-w64-mingw32-g++ -Iboost hello.cc -o hello64.exe
</pre>