After seeing truly how slow compile times with MinGW were, it wouldn’t stop bothering me. I was actively aware of how much time I was wasting and every time I hit build, I was annoyed. The computer scientist in me had to find a better solution. Compiler and build system benchmarks ensued. Jump to the bottom if all you want to see are the final results.

The first thing I realized soon after writing the last post was that I don’t really need Clang Eclipse integration, it just allows one to use Clang for the internal builder. We use CMake anyway, so all I really need is the compiler. I excitedly snapped Clang off LLVM’s website and set it up. I was so excited I even took the time to upgrade my Eclipse installation.

Clang

Appearently Clang does not have a user manual describing all of its command-line options, but it’s made fully backwards compatible with GCC. It also requires MinGW to which it has a hardcoded path of c:/mingw, so I made a symbolic link, since I didn’t want to move it to my system partition.

I quickly encountered various issues with Clang, the first one was UINT64_C(val) being defined as val##ui64 instead of val##ULL, presumably it was thinking it is a MS compiler. Perhaps a newer version of CMake would have fixed that since Clang wasn’t detected as Clang. I got around that, and some other weird things like CMake wanting to link with .lib instead of .dll. But at the linking stage a lot of warnings about duplicate definitions creeped up which I didn’t have the force to overcome. They were just warnings so the build actually finished, but the game immediately crashed. It also only finished building without errors on Release, so that’s as far as I went.

Times in seconds. First two columns taken from previous post (summed Engine and Valerie).

Pretty sweet speed-up from MinGW for full builds, but did kinda nothing for incremental builds. It also didn’t work and needed some hacking around so I wouldn’t suggest it to anyone just yet.

Make

It was more obvious than ever that it’s make’s fault, after all it was never designed for Windows. I use the port in MSYS which calls the also-ported sh to be able to start multiple jobs, so every command is passed to the bash shell for processing. With all this overhead it’s quite unsurprising it’s slow.

I found an alternate version of make which does not preserve case (csmake.exe), sounded like it should improve speed (download).

Times in seconds.

Solid improvement for just swapping an exe, but satisfying? When I look at Linux, not really. Maybe it’s possible to get fully rid of make. Was I going on another quest for the perfect build system?

Waf

Fortunately I found this truly awesome and recent benchmark of build systems. I immediately explored the winner of the benchmark: wonderbuild. It’s written in Python, which I certainly like, but as the last line of the README mentions it is currently undocumented. Big bummer, I went for waf which seemed to be actively developed and used, and whose premise excited me: it’s one tool instead of a chain of tools like cmake+make, or god-forbid autoconf+automake+libtool+make, and it’s written in an existing language (also Python). It’s unsuprisingly less popular though: 3.359 wscript files vs 58.700 CMakeList.txt files. But hey, I was desperate enough.

Creating the wscript files took some effort and a lot of looking into the documentation, and the end result was arguably less clean than CMake, because there doesn’t seem to be a way to export targets from one project and then import them in another (which in CMake we accomplish with export(TARGETS … “Targets.cmake”) and include(“Targets.cmake”)). There’s the way of creating “fake libraries” with read_shlib in the dependent project, but you lose dependency information from the original library targets which leads to duplication of the hierarchy. In fact, fake libraries defined with read_shlib cannot depend on anything, so you have to specify these additional dependencies in a different manner somewhere else. Long story short, I wasn’t pleased. If this weren’t an issue, it would have been a lot more beautiful than CMake though. To note is also that I didn’t go to the lengths to fully realize all our current build system requirements with waf, namely some annoying library searching on OS X which CMake takes care of with find_library, so I don’t know how that would have panned out.

Times in seconds.

We can see waf beats the non case preserving make heavily when no changes are made while it also improves over full build times. When your eyes glare at Linux + waf  however, you are once again left with wanting more. Here are some graphs (all data is available at Google Docs).

In the end I hooked up two old 120 GB PATA drives and put them in RAID 0. Preliminary benchmarks seem to suggest they don’t reach even half of my newer Windows drive’s I/O performance, but that doesn’t stop GCC or GNU Make from doing their job. Installed Fedora with the new GNOME 3, I’m liking it so far, finally a Linux desktop environment that doesn’t make me feel like I’m limping. It also seems to work a lot better than in Ubuntu with the Unity shell.

Related Posts: