Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate .pch for lots of headers?

Tags:

c++

gcc

clang

pch

My code uses libcxx, sdl and some other libs all the time. How can I generate .pch taking into account every header can include some other headers (even with complex conditions like #ifdef #include #endif. That's why it's difficult to understand needed header files list. Should I just use just all header files found in that folders to create .pch? What about usage of such .pch performance in that case?

UPDATE: if it matters i'm going to use it with Clang (not GCC) and to be more specific via Clang C API. UPDATE2:

i've created pch for single header file:

MBA-Anton:pch asmirnov$ clang++ -x c++-header header.h -emit-pch -o header.pch
MBA-Anton:pch asmirnov$ clang++ -include-pch header.pch source.cpp -o source -x c++

but i was unable to generate pch for multiple files:

MBA-Anton:pch asmirnov$ clang++ -x c++-header header.h header2.h -emit-pch -o headers.pch
clang: error: cannot specify -o when generating multiple output files
like image 484
4ntoine Avatar asked Nov 04 '14 06:11

4ntoine


People also ask

How do I precompile a header file?

The compiler options for precompiled headers are /Y . In the project property pages, the options are located under Configuration Properties > C/C++ > Precompiled Headers. You can choose to not use precompiled headers, and you can specify the header file name and the name and path of the output file.

Should you use precompiled headers?

Usage of precompiled headers may significantly reduce compilation time, especially when applied to large header files, header files that include many other header files, or header files that are included in many translation units.

How do you keep the same header file being added multiple times?

To avoid multiple inclusions of the same header file we use the #ifndef, #define and #endif preprocessor directives. Just write the entire program in only file and include headers once only. You can use the conditional preprocessor directive named #ifndef to check whether that symbolic name has already been assigned.


2 Answers

The GCC compiler works well only with one single included precompiled header, as explained in this answer. So if you want to use PCH in GCC, you'll need to have a single header file for all the translation units of your applications (and each of them should exactly start with that single #include directive)

I guess that such a situation is also helpful for other compilers supporting some precompiled headers.

Future versions (post C++14) of the C++ standard might define a module mechanism. See e.g. n4047 proposal.

Notice that pre-compiled headers are very compiler specific (with GCC, they might not even work when ugrading from GCC 4.9.1 to GCC 4.9.2), so you should not depend too much on them.

like image 187
Basile Starynkevitch Avatar answered Sep 27 '22 17:09

Basile Starynkevitch


First, i haven't used pch with gcc only with the microsoft compiler.

The #ifdef etc. conditions are all resolved before compilation so if you change a preprocessor variable the PCH file gets compiled anyway. So just add all the files from the lib's that you need.

Generally speaking, include all headers that are not likely to change often (i.e. external libs and parts of your system that are stable).

Don't worry too much about including headers multiple times in your pch file. Since this file will not be compiled very often you can ignore high compile times here.

What I am not sure is if the execcutable file size gets bigger when you include everything in your pch file. This might be the case because you reference otherwise not used code parts that get compiled into your executable only because you added them to your pch file. You might want to test this out.

Now, from my experience, another important question is if your compilation performance is slow when compiling or when linking.

When you have high link times the problem is more likely that you include too many headers in headers in your code.

This can be optimized by using Forward declarations in the header files and only including the headers in the .cpp files. We had huge monolithic projects and every time the biggest performance boost for compilation/linking was by removing header dependencies by forward declaring as much as possible.

This is because incremental compilation works very well but incremental linking does not.

Here is a short but good compilations of the do's and don'ts regarding forward declaration: http://www.chromium.org/developers/coding-style/cpp-dos-and-donts

like image 24
Denis Avatar answered Sep 27 '22 16:09

Denis