This article is trying to explain why and how to use pre-compiled header file to accelerate our projects compiling(not including linking) speed.
In our daily work, we modify code for fixing bugs or implementing new features, and then build new binary file and test it. The building process usually costs between 3~20 minutes. And sometimes we have to sync other colleagues’ code, the building process is much longer. So accelerating building speed is very important to improve our efficiency. Building process contains two steps. One is to compile source files and generate object files, the other is to link all object files together and generate binary file. This artical is focus on accelerating the first step.
How to use pre-compiled header
Right now many compilers, including VC++ compiler and GCC, supply a technology called pre-compiled header, which can greatly improve the compiling efficiency. Assumed there is a structure of source files.
A.cpp incudes the wx/wx.h and also does B.cpp and C.cpp. When compiling A.cpp, B.cpp and C.cpp, the compiler will parse the wx/wx.h three times. wx/wx.h is a quitely-often-used header file in our project. And there are hundreds of source files in our projects. So the wx/wx.h will be parsed hundreds of times. And there are many often-used header files like header files in std(Standard Template Library) and wxWidgets.
Pre-compiled header technology uses a common header file to generated pre-compiled header file(.pch using by VC++, .gch using by GCC). The common header file contains as many as often-used header files and we seldom change it. The former structure should be changed like the following schematic.
Now the header file called “stdwx.h” contains other often-used header files. Since the header file can not be compiled, stdwx.cpp is used to generate the pre-compiled header file. And we need to change the project build configuration like below.
For whole project,
NOTE: Actually, we can change the configuration for every single source(.cpp) file using the same method. But project-level setting is much more convenient, it can change the other source file configuration, except for those already have their own setting of precompiled header.
NOTE: stdwx.cpp is special, since the header(.h) file can not be compiled by compiler. We need a cpp file to let the compiler to compile. The content of stdwx.cpp is very simple, just include stdwx.h. So compiler will use stdwx.cpp to generate the precompiled header.
GCC supports a compile option called -x c++-header (for cpp) and c-header(for c), which used to generate the precompiled header file. Please see the following statements in makefiles.
g++ -o $@ -x c++-header -c $< -Wall -I"..."
After that, when compiler compiles the A.cpp, B.cpp and C.cpp, the stdwx.h will be parsed only once by compiling stdwx.cpp. That how the time is saved!
NOTE: The source files using pre-compiled header should include “stdwx.h” at the first line of the source, or there will be compiling errors!
The test result is very exciting! Project has 80,000 LoC.
|With Pre-compiled Header||Without Pre-compiled Header|
|Re-build Time(NOT including linking time)||30~35min||130min+|
The re-build time with pre-compiled head is only about 23% of that of without pre-compiled header project. In other words, the compiling efficiency is improved over 70%.