Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MinGW vs MinGW-W64 vs MSVC (VC++) in cross compiling

Let's put like this: We are going to create a library that needs to be cross platform and we choose GCC as compiler, it works awesomely on Linux and we need to compile it on Windows and we have the MinGW to do the work.

MinGW tries to implement a native way to compile C++ on Windows but it doesn't support some features like mutex and threads.

We have the MinGW-W64 that is a fork of MinGW that supports those features and I was wondering, which one to use? Knowing that GCC is one of the most used C++ compilers. Or it's better to use the MSVC (VC++) on Windows and GCC on Linux and use CMake to handle with the independent compiler?

Thanks in advance.

like image 772
SH.0x90 Avatar asked Jun 25 '14 20:06

SH.0x90


People also ask

Should I use MinGW or MSVC?

MSVC is doing the compilation job significantly faster than MinGW-w64. The DLL sizes are comparable, if optimization is set to "-O2" for MinGW-w64, with "-O3" the DLLs from MinGW-w64 are larger. Binary files compiled with MinGW-w64 are performing significantly better than those compiled with MSVC.

Which is better MinGW or MinGW-w64?

MinGW-w64 is a improved version which supports both 32bit and 64bit, and some more of the WinAPI (still not all, because thats much work, but more than MinGW). MinGW-w64 only provides their source code, but no binaries to "just use" the compiler.

Is MinGW a cross compiler?

As the project supports building native Windows binaries from Unix-like platforms, cross compilation is a very important part of the MinGW-w64 project.

Is GCC better than MSVC?

GCC is a fine compiler, and can produce code that has pretty much the same performance, if not better, than MSVC. It is missing some low-level Windows-specific features though.


1 Answers

Personally, I prefer a MinGW based solution that cross compiles on Linux, because there are lots of platform independent libraries that are nearly impossible (or a huge PITA) to build on Windows. (For example, those that use ./configure scripts to setup their build environment.) But cross compiling all those libraries and their dependencies is also annoying even on Linux, if you have to ./configure and make each of them yourself. That's where MXE comes in.

From the comments, you seem to worry about dependencies. They are costly in terms of build environment setup when cross compiling, if you have to cross compile each library individually. But there is MXE. It builds a cross compiler and a large selection of platform independent libraries (like boost, QT, and lots of less notable libraries). With MXE, boost becomes a lot more attractive as a solution. I've used MXE to build a project that depends on Qt, boost, and libexiv2 with nearly no trouble.

Boost threads with MXE

To do this, first install mxe:

git clone -b master https://github.com/mxe/mxe.git

Then build the packages you want (gcc and boost):

make gcc boost

C++11 threads with MXE

If you would still prefer C++11 threads, then that too is possible with MXE, but it requires a two stage compilation of gcc.

First, checkout the master (development) branch of mxe (this is the normal way to install it):

git clone -b master https://github.com/mxe/mxe.git

Then build gcc and winpthreads without modification:

make gcc winpthreads

Now, edit mxe/src/gcc.mk. Find the line that starts with $(PKG)_DEPS := and add winpthreads to the end of the line. And find --enable-threads=win32 and replace it with --enable-threads=posix.

Now, recompile gcc and enjoy your C++11 threads.

make gcc

Note: You have to do this because the default configuration supports Win32 threads using the WINAPI instead of posix pthreads. But GCC's libstdc++, the library that implements std::thread and std::mutex, doesn't have code to use WINAPI threads, so they add a preprocessor block that strips std::thread and std::mutex from the library when Win32 threads are enabled. By using --enable-threads=posix and the winpthreads library, instead of having GCC try to interface with Win32 in it's libraries, which it doesn't fully support, we let the winpthreads act as glue code that presents a normal pthreads interface for GCC to use and uses the WINAPI functions to implement the pthreads library.

Final note

You can speed these compilations up by adding -jm and JOBS=n to the make command. -jm, where m is a number that means to build m packages concurrently. JOBS=n, where n is a number that means to use n processes building each package. So, in effect, they multiply, so only pick m and n so that m*n is at most not much more than the number of processor cores you have. E.g. if you have 8 cores, then m=3, n=4 would be about right.

Citations

http://blog.worldofcoding.com/2014_05_01_archive.html#windows

like image 191
Tyler Avatar answered Sep 21 '22 14:09

Tyler