I have a very big project and for the sake of compilation speed I started to test precompiled headers.
I've setup everything now:
enable precompiled headers in VS (use them for the project, create it for the StdAfx.honly)
use multi processor compilation for all but for the StdAfx.h
automatically include the StdAfx.h in all my files via the force include of VS
The question that occurs now is following:
Do I need to remove all includes of all project files that I've added to the StdAfx.h file or is this unnecessary? Will the compiler skip any include automatically because he knows it's part of the StdAfx.h or should I remove them from each .h/.cpp file manually?
The good practice is to make each file include all the headers directly required by this file. This way changing includes in particular file should effect only this file. If you start depending on headers included somewhere else it will make your project structure extremely fragile. And the single "common includes" file is an extreme case of such scenario. Use of precompiled header supposed to speedup compilation by prebuilding commonly included header files, but project files should never assume that something is already included there. So there is no need need to remove includes from ".h/.cpp", actually there are some tools that will populate precompiled header based on includes in project files. Compiler will skip files already included in precompiled header (or in other headers) because of header guards.
I have a precompiled header that contains includes for various 3rd party libraries, e.g.:
#ifndef PRECOMPILED_H
#define PRECOMPILED_H
#include "booststuff.h"
#include "luastuff.h"
#endif
Where booststuff.h and luastuff.h are header files in my project that just include various boost / lua related things and set up some typedefs / usings / namespace aliases.
I set up the precompiled header in the usual way inside visual studio (2012), and use the force include option to include it in every cpp file.
In the cpp files, I've also been fairly careful to #include "booststuff.h" where I actually use it as well (I sometimes disable precompiled headers to test this). However, I've been wondering lately whether that's a good idea. So:
Does anything bad happen if I include a file again that's already included in the precompiled header (I don't see why it would, but I've seen things about headers having to be included "in the same order", and not really understood what they were on about)?
Does it affect Intellisense (unusably slow with a fairly small project)? I'd be happy to give up some portability for better Intellisense since I currently have no desire to switch platforms.
If each include file has #pragma once in it, the compiler will completely skip reading the file on the second and subsequent attempts to include it. It isn't stated explicitly but I assume the precompiled header tracks this information as well.
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.
Looking at an open source code base i came across this code:
#include "StableHeaders.h"
#include "polygon.h"
#include "exception.h"
#include "vector.h"
...
Now the StableHeaders.h is a precompiled header which is included by a 'control' cpp to force it's generation. The three includes that appear after the precompiled header are also included in the StableHeaders.h file anyway. My question is, are these files included twice so that the code base will build on compilers that don't support precompiled headers? As im assuming that include guards/header caching will make the multiple includes redundant anyway...
EDIT btw, the stableheaders.h file has a check for win32 (roughly) so again im assuming that the includes inside stableheaders.h wont be included on compilers that don't support precompiled headers.
Compilers that don't support precompiled headers would just include StableHeaders.h and reparse it every time (rather than using the precompiled file). It won't cause any problems neither does it fix any problems for certain compilers as you asked. I think its just a minor 'mistake' that probably happened over time during development.
I think you yourself answered the question question! Pre-compiled headers is a compiler feature. If the guard is present the headers will not be included twice, in any case.
The only reason I can think of to protect the precompiled header and include the stuff anyway is speed. The reason to use precompiled headers is to speed up the compile times, this works by including and compiling the contents of the precompiled header, when you do this you can include headers that are only used by 75% of the source files and it is still quicker than no precompiled headers.
However if the other platforms down support prepcompiled headers you only want to include the header files that are required for this source file. So if the precompiled header contains include files that are only required for by some source files it is quicker to just include and compile the header files you need.
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.