I use gcc (running as g++
) and GNU make.
I use gcc to precompile a header file precompiled.h
, creating precompiled.h.gch
; the following line in a Makefile does it:
# MYCCFLAGS is a list of command-line parameters, e.g. -g -O2 -DNDEBUG
precompiled.h.gch: precompiled.h
g++ $(MYCCFLAGS) -c $< -o $@
All was well until i had to run g++
with different command-line parameters.
In this case, even though precompiled.h.gch
exists, it cannot be used, and the compilation will be much slower.
In the gcc documentation i have read that to handle this situation,
i have to make a directory called precompiled.h.gch
and put
the precompiled header files there,
one file for each set of g++
command-line parameters.
So now i wonder how i should change my Makefile to tell g++
to create
the gch-files this way.
Maybe i can run g++
just to test whether it can use any existing file
in the precompiled.h.gch
directory,
and if not, generate a new precompiled header with a unique file name.
Does gcc have support for doing such a test?
Maybe i can implement what i want in another way?
It seems weird to answer my own question; anyway, here goes.
To detect whether a suitable precompiled header file exists, i add a deliberate error to my header file:
This works because if gcc finds a precompiled header, it will not read the
.h
file, and will not encounter the error.To "compile" such a file, i remove the error first, placing the result in a temporary file:
Here MORE_HACKERY is not just a plain file name, but contains some code to make a file with unique name (
mktemp
). It was omitted for clarity.There is a simpler way than introducing an #error in precompiled.h: never create this file at all. Neither G++ nor Visual C++ (at least up to 2005) expect the "real" file to be there, if a precompiled version is around (and if they get the necessary compilation flags).
Let's say the list of #includes that we want to precompile is called "to_be_precompiled.cpp". The filename extension doesn't matter much, but I don't like to call this a .h file, since it has to be used in a way different from genuine header files, and it's easier in Visual C++ if this is a .cpp. Then pick a different name to refer to it throughout the code, let's say "precompiled_stuff". Again, I I don't like to call this a .h file, because it's not a file at all, it's a name to refer to precompiled data.
Then in all other source files, the statement
#include "precompiled_stuff"
is not a genuine include, but simply loads precompiled data. It's up to you to prepare the precompiled data.#include "to_be_precompiled.cpp"
.In other words, you take the viewpoint that every compiler supports precompilation, but it's just a dumb copy for some compilers.