Boost logo

Boost-Build :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2004-09-03 04:14:40


Hello,
a user has asked me off-list if we could add support for precompiled headers
on msvc. Since I'd be intersted in PCH on gcc, I started to think how we can
do it.

The problem is that I never used PCH on windows, and never used then with gcc
(they were implemented recently). So, I'm not sure what the right way to use
them on either platfrom, and besides, there are some differences between
platforms. Here are my thoughts:

1. MSVC

There are automatic and manual model. In the first, one adds a compiler
option, and PCH is automatically generated used. In the second, PCH must be
explicitly created. It's created by compiling an ordinary source file with an
extra option -- a name of header file. After including that header file
during compilation, internal compiler data is dumped to PCH. During compiling
other module, the name of that header file should also be specified. The
compiler skips the that include, restores internal data from PCH, and then
compiles the rest of file as usual.

I don't know which model is better, can anyone comment on that?

The problem with manual model is that it requires that all translation units
include the same "central header", and that's terrible for compilers without
PCH. Any ideas how to fight this? Note that wrapping the content of "central
header" with

#ifdef USE_PCH
#endif

might not work -- bjam does not care for preprocessor macros so any change in
headers included from the "central header" will cause complete rebuild. OTOH,
I'd think that header should only include standard headers, not the
application's headers.

Another danger is that if all translation units include the central header,
which grabs <vector>, <map>, <algorithm> and the like, then the programmers
might forget to add those include to translation units themself, so with
"USE_PCH" undefined there will be compile errors. Seems not good for
cross-platform programming.

2. gcc

Gcc, too, has two models. You start by compiling a header file. In the first
model, the compiled header is placed somewhere in include path, and if you
try to include that header, the precompiled version is used. That is, all
translation units still have to include a central header. In the second
model, you add "-include" option to the compiler, which cause it to load the
header before compiling the translation unit. This is handy, because it avoid
modifying all translation units. The problem is still that translation unit
which uses std::vector without include <vector> will compile fine with PCH,
but won't compile elsewhere.

3. Other compilers. I know that borland has pch and vaguely remember that is
had two models similiar to msvc's, but without the need to explicitly specify
the header. I can't find any information on borland.com, so comments are very
welcome.

In conclusion, it's seems the the model with including a central header is the
lowest common denominator. Given that, the usage of pch can be something
like:

pch all : all.h app.cpp : <toolset>msvc ;
pch all : all.h : <toolset>gcc ;
alias all ; # do-nothing catch for other compilers

exe main : main.cpp all ;

The user would have to include "all.h" from every source file and wrap in in
#ifdef "BOOST_USE_PCH" -- which will be set by Boost.Build automatically.

Comments?

- Volodya

 


Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk