Pre-compiled headers : simple how to

As many of other independent developers, I don't like to use tools I'm not completely controlling and I try to reduce the complexity and dependence of my project as possible as I can. That's why most of the time I remove the stdafx.h from the projects I create and disable the pre-compiled use in the project settings.

This is a good idea if your project is using less than 10 files (and not big libraries) but it can be a really huge mistake on huge projects. My project is now using around 40 classes ( I always try to reduce it but it is sometime impossible ) so I decided to implement the precompiled header.

My compilation time is 4-5x faster than before (even more now I'm using Boost Library). I'll explain how to configure it easily.

How it works

* Why compilation is sometimes slow ? Because bigger the project is, more you have libraries/classes to include, and every time you compile a class, you compile all the files included (can be , , , ...). And this is even slower when the included classes are inlined (all the code is in the header).

* Let's say that all of your classes use the , . Why not compile the headers (not the sources) for those file once and tell every other class to use this compiled version ? That's what we call "pre-compiled" headers. Once those headers are pre-compiled the compiler can compile all the other classes withut recompiling those headers. This main issue of the pre-compiled header is that you have to include it in every sources (not headers) of your project.

How to make the pre-compiled header

* What you have to put in the pre-compiled header is all the headers you are planning to use in all your other classes. Specially the big libraries like STL, Boost, windows, glut but also the standard classes you wanna use a bit everywhere like my "template class Point..." or my class Rectangle. But avoid classes you are modifying too many times because you'll have to compile the full project again and again.

* Also put the useful functions/macro/defines/const like

#define GAME_NAME "Empire Defense"

struct DeleteObject
{
template <typename T>
void operator()(const T* ptr) const {
delete ptr;
}
};
...
static int exceptionNumber = 0;
#define TEST_FOR_EXCEPTION(throw_exception_test ,msg) \
{ \
const bool throw_exception = (throw_exception_test); \
...
}

In my project I use common.h (because I used it as a common header for all my files) as a pre-compiled header but it is more common to name it precompiled.h or stdafx.h

* Create the pre-compiled source file (in my case : "common.cpp") and include the pre-compiled header and also what need to be defined.

Using on Visual Studio

* Setting the project pre-compiled header : First, open the project property (don't forget to use all configuration) -> C/C++ -> Precompiled Headers :

  • Create/Use Precompiled Headers : Use Precompiled Header (/Yu)
  • Create/Use PCH through files : common.h (put your filename here)
  • * Setting your pre-compiled source : Open the source of your pre-compiled header properties (common.cpp for my exemple) -> C/C++ -> Precompiled Headers :

    • Create/Use Precompiled Headers : Create Precompiled Header (/Yc)
    • Create/Use PCH through files : common.h (put your filename here)
    • All is now done...

      Example

      Here is a simple example (from the game Empire Defense) of which file I included in my pre-compiled header.

      #include <stdlib.h>
      #include <math.h>
      #include <iostream>
      #include <sstream>
      #include <fstream>

      #include <string>
      #include <vector>
      #include <list>
      #include <map>
      #include <algorithm>
      #include <functional>
      #include <set>
      #include <limits>
      #include <map>

      #include <boost/serialization/access.hpp>
      #include <boost/serialization/vector.hpp>
      #include <boost/serialization/split_member.hpp>
      #include <boost/archive/text_oarchive.hpp>
      #include <boost/archive/text_iarchive.hpp>

      #include "memory.h"
      #include "log.h"

      #include "glew.h"
      #include "glut.h"

      #include "point.h"
      #include "rectangle.h"

      Conclusion

      It is a simple step to do and it is very useful
      you can now see the difference when compiling the whole program. common.cpp is compiled first and takes some time to be done and then all the other files are compiled quite fast.
      Every time you'll have to compile a file (which is not part of the pre-compiled header) you'll do it without recompiling the pre-compiled header.