gcc precompiled headers weird behaviour with -c option
March 28th, 2010Short story
Use -fpch-preprocess option alongside with -c option in order to make precompiled headers work properly.
Long story
I’m using gcc-4.4.1 on Linux and before trying precompiled headers in a really large project I decided to test them on a simple program. They “kinda work” but I was not happy with results and I was sure there was something wrong about my setup.
First of all, I wrote the following program(main.cpp) to test if they worked at all:
#include <boost/bind.hpp> #include <boost/function.hpp> #include <boost/type_traits.hpp> int main() { return 0; }
Then I created the precompiled headers file pre.h(in the same directory) as follows:
#include <boost/bind.hpp> #include <boost/function.hpp> #include <boost/type_traits.hpp>
…and compiled it:
$ g++ -I. pre.h
(pre.h.gch was created)
After that I measured compile time with and without precompiled headers:
with pch
$ time g++ -I. -include pre.h main.cpp real 0m0.128s user 0m0.088s sys 0m0.048s
without pch
$ time g++ -I. main.cpp real 0m0.838s user 0m0.784s sys 0m0.056s
So far so good! **Almost 7 times faster, that’s impressive!** Then I tried something more realistic. Since all my sources are built with -c option I tried using it and for some reason I couldn’t make pch play nicely with it. Here is what I did…
I created the test module foo.cpp as follows:
#include <boost/bind.hpp> #include <boost/function.hpp> #include <boost/type_traits.hpp> int whatever() { return 0; }
Here are the timings of my attempts to build the module foo.cpp with and without pch:
with pch
$ time g++ -I. -include pre.h -c foo.cpp real 0m0.357s user 0m0.348s sys 0m0.012s
without pch
$ time g++ -I. -c foo.cpp real 0m0.330s user 0m0.292s sys 0m0.044s
That was quite strange, looked like there was no speedup at all!(and, yes, I ran timings for several times). It turned out precompiled headers were not used at all in this case, I checked it with -H option(output of g++ -I. -include pre.h -c foo.cpp -H didn’t list pre.h.gch).
I was pretty much in despair looking at gcc’s man page and trying misc. options…until I stumbled upon -fpch-preprocess. Hell, why not try using it and it worked well all of a sudden Here is the timings:
$ time g++ -I. -include pre.h -c foo.cpp -fpch-preprocess real 0m0.028s user 0m0.016s sys 0m0.016s
I pretty vaguely understand why it worked so you if you do, please explain it in comments, I’d be very grateful for that.