I'm working on a VC++ project in VS 2012 that takes about 8-10 minutes for a full compile. I know PCH can speedup compile times by upto 10x. I have currently disabled PCH in my project and I'm including header files where they are needed. How do I get started with PCH? I've looked everywhere for "how to" guides but all I got is the docs.
I'm assuming I'll have to :
.cpp
file and place it into the PCH header fileHow do I get started with this (specifically #1)? Have you modified a project to use PCH and what are the stumbling blocks or common problems/issues therein? Can PCH cause any problems or is it just the same compile-time/runtime behaviour as normal includes? Is there a tool to automate the process or do I have to go thru 500 .cpp files by hand and modify it to use PCH?
And last but not least, what is the compilation time speedup I can expect with PCH? Is it 2x-10x? Or would it just go like 30% faster? (which does not justify the time involved)
When you create a new project in Visual Studio, a precompiled header file named pch. h is added to the project. (In Visual Studio 2017 and earlier, the file was called stdafx. h .) The purpose of the file is to speed up the build process.
Select the Configuration properties > C/C++ > Precompiled Headers property page. In the property list, select the drop-down for the Precompiled Header property, and then choose Not Using Precompiled Headers. Choose OK to save your changes. In the Solution Explorer window, right-click the pch.
To create a precompiled header file, simply compile it as you would any other file, if necessary using the -x option to make the driver treat it as a C or C++ header file. You will probably want to use a tool like make to keep the precompiled header up-to-date when the headers it contains change.
Place your caret on the first line of any C# or Visual Basic file. Press Ctrl+. to trigger the Quick Actions and Refactorings menu. Select Add file header. To apply the file header to an entire project or solution, select Project or Solution under the Fix all occurrences in: option.
Precompiled header files are an intermediate form of the header files of your project that is faster to process for the compiler. They enable rapid compiling. The file name of your precompiled header file is: <project>. pch for 32-bit Windows and macOS.
After configuring my project to use PCH, full-compile times were down to half, and incremental builds occurred almost instantly. PCH is a very effective way to speedup compile times, and I highly recommend it.
Althouh dsharlet mentions many important points, he skips some crucial steps that I had to eventually figure out. So here is the complete guide to configuring your project to use PCH:
Backup your src
dir and any other directories that contain source code ... (you'll need this in case anything goes wrong)
Create 2 files in your project, Globals.cpp
and Globals.h
.. (choose any name but stick to it)
Right click Globals.cpp
and open Properties, choose Configuration > All configurations
Go to C/C++ | Precompiled Header, and fill these in:
Open Globals.cpp
and add this one line in, and nothing more: #include "Globals.h"
Right click your VC++ project and open Properties, choose Configuration > All configurations
Go to C/C++ | Precompiled Header, and fill these in:
Open all the .h
and .cpp
files in your project, and add this at the very top: #include "Globals.h"
Open Globals.h
and add the following in: (its very important you have #pragma once
at the top)
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
#include <memory>
#include <string.h>
#include <limits.h>
#include <float.h>
#include <time.h>
#include <ctype.h>
#include <wchar.h>
#include <wctype.h>
#include <malloc.h>
#include <locale.h>
#include <math.h>
// Windows SDK
#define _WIN32_WINNT 0x0501 // _WIN32_WINNT_WINXP
#include <SDKDDKVer.h>
// Windows API
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
Using find and replace, search for each of the #include
's in your PCH file, and remove them from all the .h
and .cpp
files in your project.
Do a full compile and ensure everything is working okay. Here are some solutions for common problems you'll encounter:
PCH file includes itself:
Your PCH file is including a header that includes the PCH header file again, creating a kind of circular dependency. Double click the error to take you to the offending file, and simply remove the line that says #include "Globals.h"
Undefined symbol X
Although all your project files can include the PCH header, the files included inside the PCH header cannot include the PCH header! (as stated above) so you'll need to add back any imports that were previously in the file. (diff the file with the backup version)
Cannot find symbol logf
Sometimes the global PCH file does not behave as expected, and breaks compiling with crazy errors that are impossible to solve. You can then turn off PCH for individual source code files.
Right click your .cpp
file and open Properties, choose Configuration > All configurations
Go to C/C++ | Precompiled Header, and fill these in:
Remove the line #include "Globals.h"
in your .cpp
file
Add back whatever imports the file originally had. (diff the file with the backup version)
Here's how I use PCH with decent results:
At this point, the project should still build and behave exactly as it used to, but there may not be any real improvement in compile time. Now, you'll need to move some of your #include "...h" to the PCH header file (and delete the includes of those files from elsewhere in the project). The includes that you should move to the PCH header should be headers that are included in many files, but change infrequently. Examples: STL headers, windows.h, core functionality headers from your project, etc.
Once PCH is set up, it should be transparent. It's basically just helping the compiler cache some intermediate compilation data. In other words, if you turned off PCH in your project, everything should still build exactly as it would have with PCH turned on (except slower!)
The speedup entirely depends on how much code is moved into the PCH (how much included code from headers is moved from arbitrary cpp files to the PCH header). I've seen multiple times improvement, but haven't benchmarked it precisely. I definitely felt like it was worth doing when I've gone through the trouble to use PCH on a big project.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With