There's a code that includes a lot of standard library headers. The code is situated in one file, and I cannot create any other C++ source files in that project (sic). I would like to increase the performance of the build process using precompiled headers. There're two problems
Trying to use this guide on vector, I've got a file format not recognized error. What flags should I set to show gcc that it's a header file?
There's a quote in official guide that says "Only one precompiled header can be used in a particular compilation". How do I precompile several headers at once then?
(Any batch/shell scripts appreciated too.)
Didn't you forget to use -x option for compiling your precompiled header as documentation states? Next if you want to have Standard Library's templates precompiled - it's impossible by definition. Using C++11 you can explicitly instantiate some templates in some particular translation unit for certain type arguments. From precompiled header you can specify
extern template void foo<char>(...)
What's the use of precompiled headers if you are trying to use them against templates? Your precompiled header must be a set of other includes/macros definitions/inline functions and everything else that can be safely included into multiple translation units. And yet - only one precompiled header per library/binary.
Related
Apparently it is recommended to force include precompiled headers, so that the source may be used with and without precompiled headers. Even CMake uses the force include method on precompiled headers.
However for example Microsofts MSVC documentation says:
The compiler treats all code occurring before the .h file as precompiled. It skips to just beyond the #include directive associated with the .h file, uses the code contained in the .pch file, and then compiles all code after filename.
and for the /FIoption the documentation says:
This option has the same effect as specifying the file with double quotation marks in an #include directive on the first line of every source file specified on the command line, in the CL environment variable, or in a command file.
So to summarize this: All includes that are above/before an include directive of a corresponding precompiled header, will be precompiled into the PCH file. Force-including that file will put this in the first line of a file.
My question now is: How does this work together? Is there some special logic for PCH files during build process or am I missing something?
Update: I checked the gcc documentation as well and it looks like that gcc searches for precompiled headers for each include directive it finds and uses precompiled headers if possible. So do I understand it correctly that MSVC kind of summarizes all includes before (including the header itself) an include that should be used to generate a precompiled header, where gcc instead generates a precompiled header for that specific header?
If that's right it arises the question: Is gcc really way more flexible regarding preocmpiled header usage and how easy it is to gain a performance boost during compilation out of it?
First of all i want to say that I read about precompiled headers and I understand that this is an optimization that saves me the time of compiling headers over and over on every built.
I'm reading the documentation of boost and I see that in the instructions they say:
In Configuration Properties > C/C++ > Precompiled Headers, change Use Precompiled Header (/Yu) to Not Using Precompiled Headers
And then they explain it:
There's no problem using Boost with precompiled headers; these instructions merely avoid precompiled headers because it would require Visual Studio-specific changes to the source code used in the examples.
Can some explain me the sentence I marked in bold? which visual studio specific changes they are talking about ? (Here is the link to the documentation I'm reading: http://www.boost.org/doc/libs/1_55_0/more/getting_started/windows.html#pch)
Why and when I would want to turn off the precompiled headers?
what is the difference between "Create" and "Use" in the precompiled header options.
Originally a comment, but I may as well post it. Note: this is specific to VC++:
The bold sentence is their way of saying the samples don't follow the mantra of a unified use-this-lead-in-header-for-pch-generation model. IOW, their samples aren't PCH-friendly, but you can still use pch with boost in your projects if properly configured.
You would turn them off for a variety of reasons. Some source modules, particularly ones from 3rd-parties, don't follow the PCH model of including "the" pch-through-header at their outset. Their samples are such code (and thus the advise to turn them off for their samples). Sometimes source files require different preprocessor configurations only for this files and not all files int he project; another reason to disable PCH for those files.
You typically use a source/header pair to generate "the One"; the precompiled header image. This header file typically includes:
Any system standard lib headers used by your project
3rd-party SDK headers
Just about everything else that is NOT in active development for your project.
The single source file tagged as Create typically includes one line of code : #include "YourHeaderFile.h", where YourHeaderFile.h is the header you filled with stuff from the list above. Tagging it as "Create" through header YourHeaderFile.h tells VC it is the file needed for rebuilding the PCH through that header when compiling other source files. All other source files are tagged as Use (except the ones where PCH is turned off) and should include, as their first line of code, the same #include "TheHeaderFile.h".
In short (hard to believe), <boost> is telling you their samples aren't setup like described above, and as such you should turn PCH off when building them.
When you use pre-compiled headers, you need to do something like:
#include <foo>
#include <bar>
#include <baz>
#pragma hdrstop
// other code here
Everything before the #pragma goes into the precompiled header. Everything after it depends on the precompiled header. The VC++ specific "magic" to make pre-compiled header work is that #pragma.
There's a little more to the story than just that though. To make pre-compiled headers work well, you want to include exactly the same set of headers in exactly the same order in every source file.
That leads to (typically) creating one header that includes all the other common headers and has the #pragma hdrstop right at its end, then including that in all the other source files.
Then, when the compiler does its thing, there are two phases: first you need to create a pre-compiled header. This means running the compiler with one switch. The compiler only looks at what comes before the #pragma hdrstop, builds a symbol table (and such) and puts the data into a .pch file.
Then comes the phase when you do a build using the pre-compiled header. In this phase, the compiler simply ignores everything in the the file up to the #pragma hdrstop. When it gets to that, it reads the compiler's internal state from the .pch file, and then starts compiling that individual file.
This means each source file typically includes a lot of headers it doesn't actually need. That, in turn, means that if you don't use pre-compiled headers, you end up with compilation that's much slower than if you hadn't done anything to support pre-compiled headers at all.
In other words, although the only part that's absolutely required is the #pragma hdrstop, which is fairly innocuous, a great deal more file re-structuring is needed to get much benefit from them--and those changes are likely to actively harmful to compilation time if you're using anything that doesn't support pre-compiled headers (and in the same way VC++ does them at that).
When precompiled headers is on every cpp source file must start with #include "stdafx.h"
So you would turn it off if you do not want to edit all the boost source files.
When precompiled headers is on stdafx.cpp "creates" the precompiled header. All other files "use" the precompiled header.
After reading this nice article (The Care and Feeding of Pre-Compiled Headers), I have some doubts regarding how these can actually work in real life. More specifically, how can I know that I need to trigger the rebuild of the pre-compiled header in the following scenarios:
I decide to #define something in one of my .cpp files that alters the way the pre-processor interprets some headers that are already included in my pre-compiled header
I include another header in one of my .cpp files which #defines a specific pre-processor directive that alters the way the pre-processor interprets a header already included in the precompiled header
Even worse, the previous issue can happen recursively, when certain headers #include other headers
Should the usage of pre-compiled headers enforce a certain restrictive coding style like limiting the number of headers included in .cpp files to one and never #defineing stuff in a .cpp file?
While Microsoft's compiler probably does a decent job with pre-compiled headers (by applying some MS-specific voodoo) because, as far as I know, it provides the /Yc and /Yu options that are supposed to do all the plumbing, for GCC it seems that this functionality requires a lot of manual work and creativity in the Makefile and I wasn't able to find a template that is supposed to address all the pitfalls of using pre-compiled headers.
For example, if I have a project which builds several libraries, in order not to rebuild all of them after each change, I have to use some really cute sed tricks in the Makefile to detect if one of the headers #included by the current library was modified (or it #includes a modified header). I fear to even think of the complications that pre-built headers would actually imply in order for the build script to rebuild them each time it is necessary.
Current GCC (i.e. 4.7) and previous versions of it works nicely with precompiled headers only when you have a single common header to your application, and when that single header (which includes in turn all the system ones, and the library specific ones, required by the application) is #include-d (as the first non-comment lexeme of your sources) by every source of your application.
So you should have a single yourapp.h and have every source file (i.e. every compilation unit) of yourapp starting with #include "yourapp.h" with the same preprocessing options (i.e. -D or -I or -U) on the command line. That youapp.h header file is usually #include-ing many others, e.g. system headers (or GTK or Qt ones) like <stdlib.h> or <sys/poll.h> or [in C++] <algorithm> or <gtk/gtk.h> or <QtGui> etc.
Recall that -H is a useful option to get gcc tell you what is included.
Your source files might have some additional #include after #include "yourapp.h" if so wanted.
After a [single] precompiled header has been included by GCC, you may of course #define macros, #include some non-precompiled header, do conditional compilation with #ifdef, etc. But that preprocessing won't be "pre-compiled"!
This may not fit your needs or habits.
Some people (notably from Google, notably Diego Novillo) are working on the PreParsed Header (pph) branch to improve the situation, but the current GCC trunk has not got that work yet.
The explanation about that behavior of GCC is that a preprocessed header is essentially a persistent serialized checkpoint of the entire GCC heap (related to memory management inside GCC thru Ggc and GTY and gengtype). That checkpointed heap can be loaded only when gcc is in its initial empty state. As soon as something is known to gcc (actually cc1 or cc1plus) it cannot load any more any precompiled header file *.h.gch and will revert to parsing the textual header file *.h.
addenda (november 2014 and later)
Even GCC 4.9 wants a single precompiled header. The pre-parsed header effort by Diego Novillo et al. has been abandoned.
Future versions (post C++14) of the C++ standard might define a module mechanism. See e.g. n4047 proposal and the C++20 standard.
(additional addenda, summer 2020) This still holds for GCC-10 where several static analyzer options exist. See also the Clang static analyzer and this draft report. Consider using Frama-C.
Sometimes it would be useful to know whether the compiler requires a pre-compiled header or not, and how the header file is called. My goal is to add some preprocessor directives like this:
#ifdef REQUIRES_PRECOMPILED_HEADER
#include PRECOMPILEDHEADER_FILE
#endif
So my question is: Are there predefined variables like REQUIRES_PRECOMPILED_HEADER and PRECOMPILEDHEADER_FILE?
Well presumably your source files will not need any of the headers included in the precompiled header. So, if you are trying to include your source files in a project where other source files do use precompiled headers, just make sure precompiled headers are turned off for yours.
Just select the properties for your source files, and under "Precompiled Header" select "Not Using Precompiled Headers".
It's not your task to support others' use of precompiled headers. It's up to them to add your header to their precompiled header, or not. You just create trouble by trying to do it for them.
So, problem solved: don't do that.
It's unnecessary and it creates trouble.
I've got a bunch of legacy code that I need to write unit tests for. It uses pre-compiled headers everywhere so almost all .cpp files have a dependecy on stdafx.h which is making it difficult to break dependencies in order to write tests.
My first instinct is to remove all these stdafx.h files which, for the most part, contain #include directives and place those #includes directly in the source files as needed.
This would make it necessary to turn off pre-compiled headers since they are dependent on having a file like stdafx.h to determine where the pre-compiled headers stop.
Is there a way to keep pre-compiled headers without the stdafx.h dependencies? Is there a better way to approach this problem?
Yes, there is a better way.
The problem, IMHO, with the 'wizard style' of precompiled headers is that they encourage unrequired coupling and make reusing code harder than it should be. Also, code that's been written with the 'just stick everything in stdafx.h' style is prone to be a pain to maintain as changing anything in any header file is likely to cause the whole codebase to recompile every time. This can make simple refactoring take forever as each change and recompile cycle takes far longer than it should.
A better way, again IMHO, is to use #pragma hdrstop and /Yc and /Yu. This enables you to easily set up build configurations that DO use precompiled headers and also build configurations that do not use precompiled headers. The files that use precompiled headers don't have a direct dependency on the precompiled header itself in the source file which enables them to be build with or without the precompiled header. The project file determines what source file builds the precompiled header and the #pragma hdrstop line in each source file determines which includes are taken from the precompiled header (if used) and which are taken directly from the source file... This means that when doing maintenance you would use the configuration that doesn't use precompiled headers and only the code that you need to rebuild after a header file change will rebuild. When doing full builds you can use the precompiled header configurations to speed up the compilation process. Another good thing about having the non-precompiled header build option is that it makes sure that your cpp files only include what they need and include everything that they need (something that is hard if you use the 'wizard style' of precompiled header.
I've written a bit about how this works here: http://www.lenholgate.com/blog/2004/07/fi-stlport-precompiled-headers-warning-level-4-and-pragma-hdrstop.html (ignore the stuff about /FI) and I have some example projects that build with the #pragma hdrstop and /Yc /Yu method here: http://www.lenholgate.com/blog/2008/04/practical-testing-16---fixing-a-timeout-bug.html .
Of course, getting from the 'wizard style' precompiled header usage to a more controlled style is often non-trivial...
When you normally use precompiled headers, "stdafx.h" serves 2 purposes. It defines a set of stable, common include files. Also in each .cpp file, it serves as a marker as where the precompiled headers end.
Sounds like what you want to do is:
Leave precompiled header turned on.
Leave the "stdafx.h" include in each .cpp file.
Empty out the includes from "stdafx.h".
For each .cpp file, figure out which includes were needed from the old "stdafx.h". Add these before the #include "stdafx.h" in each .cpp file.
So now you have the minimal set of dependancies, and you still are using precompiled headers. The loss is that you are not precompiling your common set of headers only once. This would be a big hit for a full rebuild. For development mode, where you are only recompiling a few files at a time, it would be less of a hit.
No, there is probably NOT a better way.
However, for a given individual .cpp file, you might decide that you don't need the precompiled header. You could modify the settings for that one .cpp file and remove the stdafx.h line.
(Actually, though, I don't how the pre-compiled header scheme is interferring with the writing of your unit tests).
No. pre-compiled headers relies on a single header included by all sources compiled this way.
you can specify for a single source (or all) not to use pre-compiled headers at all, but that's not what you want.
In the past, Borland C++ compiler did pre-compilation without a specific header. however, if two sources files included the same headers but at different order, they were compiled separately, since, indeed, the order of header files in C++ can matter...
Thus it means that the borland pre-compiled headers did save time only if you very rigidly included sources in the same order, or had a single include file included (first) by all other files... - sounds familiar ?!?!
Yes. The "stdafx.h/stdafx.pch" name is just convention. You can give each .cpp its own precompiled header. This would probably be easiest to achieve by a small script to edit the XML in your .vcproj. Downside: you end up with a large stack of precompiled headers, and they're not shared between TU's.
Possible, but smart? I can't say for sure.
My advice is - don't remove precompiled headers unless you want to make your builds painfully slow. You basically have three options here:
Get rid of precompiled headers (not recommended)
Create a separate library for the legacy code; that way you can build it separately.
Use multiple precompiled headers within a single project. You can select individual C++ files in your Solution Explorer and tell them which precomiled header to use. You would also need to setup your OtherStdAfx.h/cpp to generate a precompiled header.
Pre-compiled headers are predicated on the idea that everything will include the same set of stuff. If you want to make use of pre-compiled headers then you have to live with the dependencies that this implies. It comes down to a trade-off of the dependencies vs the build speed. If you can build in a reasonable time with the pre-compiled headers turned off then by all means do it.
Another thing to consider is that you can have one pch per library. So you may be able to split up your code into smaller libraries and have each of them have a tighter set of dependencies.
I only use pre-compiled headers for the code that needs to include the afx___ stuff - usually just UI, which I don't unit-test. UI code handles UI and calls functions that do have unit-tests (though most don't currently due to the app being legacy).
For the bulk of the code I don't use pre-compiled headers.
G.
Precompiled headers can save a lot of time when rebuilding a project, but if a precompiled header changes, every source file depending on the header will be recompiled, whether the change affects it or not. Fortunately, precompiled headers are used to compile, not link; every source file doesn't have to use the same pre-compiled header.
pch1.h:
#include <bigHeader1.h>
#include ...
pch1.cpp:
#include "pch1.h"
source1.cpp:
#include "pch1.h"
[code]
pch2.h:
#include <bigHeader2.h>
#include ...
pch2.cpp:
#include "pch2.h"
source2.cpp
#include "pch2.h"
[code]
Select pch1.cpp, right click, Properties, Configuration Properties, C/C++, Precompiled Headers.
Precompiled Header : Create(/Yc)
Precompiled Header File: pch1.h
Precompiled Header Output File: $(intDir)pch1.pch
Select source1.cpp
Precompiled Header : Use(/Yu)
Precompiled Header File: pch1.h
Precompiled Header Output File: $(intDir)pch1.pch (I don't think this matters for /Yu)
Do the same thing for pch2.cpp and source2.cpp, except set the Header File and Header Output File to pch2.h and pch2.pch. That works for me.