The problem: n bit system, wanting to build n bit by default, but also being able to build BOTH 32 and 64 bit for certain tools (like SDL and the SDL game you're developing for example…) Trying to do so by simply specifying the appropriate gcc is apt to fail because non-gcc binutils like windres.exe will do EITHER 64 or 32 bit, but not both. You can twiddle your path, but twiddling paths isn't something a build script ought to be doing.
The solution: Building for i686 on an x86_64 system is a cross-compile even if doesn't look like one. If binutils were installed with i686-w64-mingw32- prefixes on the binaries and you're using a cross-compile-aware build system, something like this for autoconf should just work:
THEN, if your autoconf-based program's build system isn't buggy, you can do this:
#! /bin/sh
MULTI_BUILD_ARCHS="i686-w64-mingw32 x86_64-w64-mingw32"
for arch in ${MULTI_BUILD_ARCHS}; do
mkdir -p build-${arch}
( cd build-${arch} && ../configure --target=${arch} "$@" )
( cd build-${arch} && make )
done
…or something more complete/proper. I'd suggest modifying the binutils install to provide versions both with and without the target prefix, regardless of whether or not it's needed. The appropriate one goes into your path first because we don't have a toolchain-select tool and if you want one you can add some path twiddling stuff to your bashrc.
To reduce the headaches for the SDL developer list, my MSYS2-based setup guide for a working 32/64-bit MingW-w64 build environment for SDL will include creating a dir full of symlinks for both toolchains' binutils packages with target prefixes. My understanding is this requires NTFS and the solution is IMO ugly. It'll work, though, and it will survive upgrades to binutils packages including one that obsoletes its existence. (I want to run that guide by a few people involved with the MSYS2 project before publication because the net does not need another bad set of instructions for setting up a MingW environment!)
FWIW, I am open to being told I'm doing this wrong, provided there's a reference to how to do it right. AFAICT, windres.exe for x86_64 produces output that cannot be linked by a 32 bit toolchain. Which broke an earlier SDL2 build outright since it actually hardcoded the windres.exe binary name. It did that because support for Windows resources is not even an afterthought in autoconf, but it's always a bug to hard-code the name of a binary buried deep on some Makefile.in. :)
You can't build 64 bit software on a 32 bit Windows with MSYS2. This is because our compilers are not multlib enabled as we want different exception models for i686 and x86_64 and that's not possible with GCC at present.
You absolutely should be manipulating your PATH and MSYSTEM env. variables to achieve your goals. In fact you should use mingw32_shell.bat and mingw64_shell.bat which do exactly this.
Thanks for taking the time to ask. In my opinion the symlink thing is horrible.
Agreed about the symlink directory thing. It's a mess and intended to be temporary.
Nonetheless, binutils is architecture-specific and if you're building for i686 on x86_64 systems, ./configure --target=i686-w64-mingw32 should work, but doesn't. First it fails because SDL incorrectly assumes that windres is platform-independent and it's not (fixed with AC_CHECK_TARGET_TOOL instead of AC_CHECK_TOOL), and secondly because there isn't a properly-named i686-w64-mingw32-windres.exe my path.
If I can't install it, I've got to create it, which is ugly. Hence the ticket. :)
There are two windres executables. One in /mingw32/bin and the other in /mingw64/bin and they generate the architecture appropriate object file, so prepending /mingw32/bin or /mingw64/bin to PATH should cause the right one to be found.. unless I am missing something here? I'm not at a computer and can't check until tomorrow.
And you can technically build binaries for the Commodore 64 if you have a gcc suite and binutils in your path that cross-compile to that architecture. But the standard architecture-independent way to do it described in numerous sources (such as http://wiki.freepascal.org/Setup_Cross_Compile_For_ARM or http://wiki.osdev.org/GCC_Cross-Compiler for examples) is for toolchains to be built with the appropriate prefixes.
I note the osdev.org refers you to old/obsolete instructions for MingW32 with the original MSYS from 2008, which is the kind of thing I'd like to get people to stop doing.
Essentially it boils down to autoconf having a built-in mechanism for allowing you to select from amongst a group of installed toolchains with a single argument passed to ./configure. This works if your binutils was installed in the traditionally-expected manner for doing that. MSYS2 does not install binutils in that fashion and falls back upon path hacking tricks.
It should be possible to cross-compile 64 bit bins and libs on 32 bit systems. They won't run there, but that's what cross-compiling is all about. It just so happens that if you cross-compile a 32 bit bin/lib on a 64 bit machine, you can run the result. Theoretically you could target WinRT (dunno if Microsoft will accept anything thus built for the Windows Store so I doubt there's reason to), but there's no technical reason it can't be done.
The three batch files are hardly necessary. Indeed, if you're using ConsoleZ or similar, they're wholly unnecessary. Set your working directory appropriately and set MSYSTEM as you want it. Or, if binutils is modified as I propose, it becomes pretty trivial to create a mingw-select tool and have the MSYSTEM environment variable simply be used to ensure that the correct toolchain is selected. That gives you future-compatibility with CLang or other LLVM-based compiler without an exponential multiplication of effort.
There are reasons to use gcc over clang, but if it were more mature clang is the more reasonable default choice and the one I'd pick myself. That's a slightly bigger issue above and beyond binutils, but the time to solve these kinds of problems is before you need it, not afterward. (But that's a ticket for the filesystem package with insistence on a patch before the discussion goes too far and I need to get this SDL stuff done first. I'll provide a patch for binutils as well, if a patch would be welcome.)
MSYS2 often refers to two things. The MSYS2-shell itself, and the MSYS2/MinGW-w64 pacman system built on this shell.
If you are talking about using the MSYS2-shell as your build environment then great, feel free to build whatever cross compilers you want targeting whatever systems you want.
However, MSYS2/MinGW-w64 is a system for native compilation (and distribution) of Windows software, it's not not about cross compilation. The packages in http://downloads.sourceforge.net/project/msys2/REPOS/MINGW/i686 and http://downloads.sourceforge.net/project/msys2/REPOS/MINGW/x86_64 are natively compiled.
We provide three batch files that set up the environment correctly for people who want to use build systems directly (autotools, cmake, qmake etc). Setting PATH in these batch files is neither a hack nor a trick, it's the correct thing to do. Yes, experts who know the details can set PATH and MSYSTEM themselves, but not everyone knows or cares. FWIW, makepkg-mingw should be run from msys2_shell.bat as it does the PATH / MSYSTEM manipulation as it runs.
The correct parallel term in ArchLinux for MSYS2/MinGW-w64 is "multilib". Multilib ArchLinux would never be described as a cross compilation system.
In the interests of pragmatism, I would not be opposed to merging a change to binutils that also created {i686,x86_64}-w64-mingw32-windres.exe, but I do stress that you are thinking about MSYS2/MinGW-w64 in a way that it's creators would caution against.
Diff: