Recently I've attempted to reduce the build times of a client's project - said project takes about 90 minutes to build from scratch on a Windows box using Visual Studio .NET (2003). I do realise that one of the easier ways to shorten build times is to simply move to 2005 and make use of its parallel build feature. While that is on the cards, the actual speedup from a move to 2005 isn't as big as I hoped for. VS2005 does only build (sub)projects in parallel, and two subprojects do take a disproportionate amount of time to build.
This project is cross-platform and as such, I was looking for minimal invasive surgery on the build process to speed up the Windows build process without affecting any of the other platforms. A lot of the Old School ways of improving build times had already been applied - for example, the include guards are checked in the including files to prevent double inclusions (as John Lakos recommended in his book "Large Scale C++ Programming"), almost all headers have include guards and so on.
My first thought - which was anything but minimally invasive - was to add a suitably protected '#pragma once' to all includes. When I did measure the resulting build times I was a bit surprised - on my desktop machine, there was no difference in build time outside the measuring tolerance. On the laptop that I work on when working remotely, there was a measureable acceleration, but we're still talking in the order of 5%, up to about 8%-9% on a really good run. It seems that VS 2003 is already doing a pretty good job of caching headers, so the difference that #pragma once make seem to show mainly on machines with relatively little RAM and slow harddisks. At this point I went onto another Google spree and found that this article on Games From Within had arrived at the same conclusions. Which left only one obvious way of improving build times and that was by using precompiled headers for the Windows build. And the Windows build only...
The obvious way to use precompiled headers would have been to create a script that iterates over all .cpp files in the project, checks them out from version control and adds the line including the precompileable header. Such a script is not exactly hard to write - depending on the version control system you're using, you may not even have to check out the files before being able to change them. Nevertheless, this approach very much violated the 'minimally invasive' requirement. In other words, I didn't want to change the source code at all.
The one solution that I ended up using was one that may well be obvious to the Visual Studio gurus out there - the compiler supports a 'force includes' switch (which you can find in the C/C++ Advanced settings in the GUI). Amazingly enough, this setting works with precompiled includes as well, so you can specify the precompileable header as a forced include, invisible to the rest of the code. Everything else works as expected, so you set the precompiled header directives for the compiler as usual.
It was a bit more effort to change the build this way but in the end it was worth it. Just reworking the four subprojects that took longest to rebuild reduced the overall build time by nearly thirty minutes.
Now all I need to do is find a similar method that works with GCC...