How to Create Precompiled Header Files.

Author: Chang Hee Kim, a.k.a., As.G. Thomas Kim

http://www.TalkPlayFun.com

http://www.TranslatorsFrom.Asia

First Edit: Feb. 10, 2017

If you haven’t watched YouTube video yet, please watch it first before you read it.

When we are developing C/C++ applications using Visual C++, especially when our computer is very slow (like mine), creating precompiled header files in the Visual C++ project helps boost the compiling processes much faster than when not using it. The concept of Precompiled Header Files is very simple, (1) just include all standard C/C++ header files that you need, such as iostream, cstdio, windows.h, atlbase.h, etc., in your stdafx.h file, and (2) include stdafx.h at the beginning section of all *.cpp code files using #include preprocessor directive.

For example, if we have the following list of files in our C++ project:

  1. source.cpp -- main() source code file;
  2. MyObject.h -- your custom class’, CMyObject, header file;
  3. MyObject.cpp - your custom class’ source code file.

Then add two more additional files to your project as below:

  1. stdafx.h - header file to include standard C++ header files;
  2. stdafx.cpp - source code file to compile for the precompiled header files’ database.

Since we are going to include all necessary C/C++ standard header files in stdafx.h, we need NOT include them either in our custom header files (*.h), such as MyObject.h, or in our source code files (*.cpp), such as source.cpp or MyObject.cpp. We include ONLY standard header files ONLY in the stdafx.h, OR those header files that do not, or infrequently, change in the course of our development. Also, each time we make changes to the stdafx.h, we have to recompile stdafx.cpp, whose sole purpose is to create the precompiled header files’ database for our project. Usually, the content of stdafx.cpp is a single line of text, i.e., #include "stdafx.h"

 We need to make correct settings for the project file. Suppose we have a Visual C++ solution called PrecompiledHeaderSolution, and a project called MyConApp which consists of three following files:

  1. source.cpp -- main() source code file;
  2. MyObject.h -- your custom class’, CMyObject, header file;
  3. MyObject.cpp - your custom class’ source code file.

Then we need to add two additional files, one header file stdafx.h and one source code file stdafx.cpp to our project MyConApp:

  1. stdafx.h - header file for the inclusion of standard C++ header files;
  2. stdafx.cpp - source code file to be used to generate precompiled header files’ database.

Instead of stdafx.h and stdafx.cpp, we can name these two files arbitrarily as we like, but these file names are traditionally accepted as standard convention (at least in Visual C++ community), such that any Visual Studio developers can readily understand their sole purpose in the project. Traditionally, the content of stdafx.cpp is a single line of text, #include "stdafx.h", and each time we make changes to stdafx.h, we have to compile it again to reflect the changes in the compiled header files’ database (*.pch). When stdafx.cpp is compiled, precompiled header files’ database is created. This file is by default named $(TargetName).pch, where $(TargetName) is our C/C++ project’s name, in our case, MyConApp. So when we compile stdafx.cpp, MyConApp.pch will be generated in the target directory folder. In Visual C++, $(IntDir) is a macro that is expanded to target directory. Again in Visual C++, $(TargetName) is a macro that is expanded to a project name, in our case, it is MyConApp. We can build both Win32 or 32-bit application and x64 or 64-bit application using the same source code in Visual Studio. The macro $(PlatformTarget) will be expanded either as x86 in the Win32 or 32-bit build and x64 in 64-bit build respectively. Since these three macros, $(IntDir), $(TargetName), and $(PlatformTarget) are quite frequently used, these deserve to be committed in our memory.

For more details about Precompiled Header Files used in Visual C++, please refer to “Creating Precompiled Header Files” from Microsoft Documentation website. Please note that the above link can be changed in the future, in such case search for “Creating Precompiled Header Files” using google search.

To grasp solid understanding of Precompiled Header Files, we will

  1. create a solution named PrecompiledHeaderSolution with an empty Win32 Console Application project named MyConApp in it;
  2. add stdafx.h and stdafx.cpp files to Header Files folder and Source Files folder respectively in the Solution Explorer;
  3. make Precompiled Header settings (/Yu) for MyConApp project in the MyConApp Property Pages.
  4. make Precompiled Header settings (/Yc) for stdafx.cpp file in the stdafx.cpp Property Pages;
  5. add a custom C++ class, CMyObject to our project. This class will be defined in the MyObject.h and its source code in MyObject.cpp;
  6. add Source.cpp file to the Source Files folder of our project MyConApp. The function main() will reside in this file;
  7. build the solution and execute it, and examine the created precompiled header files’ database MyConApp_x86.pch. $(PlatformTarget) macro expands to x86 when building Win32 platform.
  8. change platform to x64 or 64-bit, build the solution, and examine the precompiled header files’ database MyConApp_x64.pch.

Please watch YouTube video before we go further reading.

Hands-on Experience

STEP 1. Create Visual C++ solution with an empty Win32 Console Application. The solution name is PrecompiledHeaderSolution, and the project name is MyConApp using Visual Studio 2015.

Click File, then select New, Project in sequence, or press Ctrl+Shift+N keyboard shortcut.

01-File-New-Project.PNG

(To view big image, right-click the picture and select Open image in new tab)

The New Project dialog box opens. Select Installed, Templates, Visual C++, Windows, Win32 in the left-hand side in sequence. Select Win32 Console Application in the middle of the dialog box. Then enter MyConApp in the Name: field, and PrecompiledHeaderSolution in Solution name: field as shown below:

02-MyConApp.PNG

(To view big image, right-click the picture and select Open image in new tab)

Click OK button on the bottom right corner. We will have another dialog box shown below:

03-MyConApp-Next.PNG

Simply click Next > button. Do NOT click Finish yet. Then we will have another dialog box open shown below:

04-Empty-Project.PNG

(To view big image, right-click the picture and select Open image in new tab)

Select Console application as Application type, and click to select Empty project in the Additional options check box, click Finish to create the solution. We have now created an empty Win32 Console Application called MyConApp with solution name  PrecompiledHeaderSolution. Since we selected Empty project, we have no files in our project yet.

STEP 2. We add stdafx.h and stdafx.cpp to our project in the folder Header Files and Source Files folder respectively. To add stdfax.cpp source file, right-click Source Files folder, select Add, New Item in the Solution Explorer in sequence.

05-add-new-to-source.PNG

If Solution Explorer is not open in Visual Studio, you can open it by pressing Ctrl+Alt+L keyboard shortcut, or selecting View menu, then Solution Explorer. We will have Add New Item - MyConApp dialog box open, in which we select Installed, Visual C++ in the left-hand side, and select C++ File (.cpp) in the middle, enter stdafx.cpp in the Name: field, then click Add button at the bottom right corner of the dialog box.

06-add-stdafx-cpp.PNG

Now we will add stdafx.h in the Header Files folder of the project MyConApp. In the Solution Explorer, right-click Header Files folder, select Add, then New Item in sequence as shown below:

07-add-new-to-header.PNG

(To view big image, right-click the picture and select Open image in new tab)

If Solution Explorer is not open, press Ctrl+Alt+L keyboard combinations. Then we will have Add New Item - MyConApp dialog box open, in which select Installed, Visual C++, Code in the left-hand side, and Header File (.h) in the middle, type in stdafx.h in the Name: field, click Add button at the bottom right corner as shown below:

08-add-stdafx-h.PNG

We now have added stdafx.h and stdafx.cpp to our project as below:

09-stdafx-h-cpp.PNG

STEP 3. We now have to make changes to our project settings. To do this, right-click MyConApp in the Solution Explorer, then select Properties as shown below:

10-MyConApp-properties.PNG

In the MyConApp Property Pages dialog box (see below), make sure All Configurations and All Platforms are selected as in the screenshot. Click Configuration Properties, C/C++, then Precompiled Headers in the left-hand side in sequence, if not already selected.

11-MyConApp-properties-page-1.PNG

Click inside of Precompiled Header editor box, then a drop-down downward arrow button appears on the right edge unfolding a list of choices, then select Use (/Yu) choice as shown below:

11-MyConApp-properties-page-2.PNG

The result of our choice should look like below. Please remember that we must select Use (/Yu) as Precompiled Header for our project MyConApp. We will select Create (/Yc) as Precompiled Header for stdafx.cpp in the next step. Do not get confused, we have to select Use (/Yu) for the project’s Precompiled Header option, and Create (/Yc) for stdafx.cpp in the next step. Don’t click OK button yet. We still have to make another change to this dialog box.

11-MyConApp-properties-page-3.PNG

If we click Precompiled Header Output File edit field, a drop-down downward arrow button appears on its left edge. Click this downward arrow button to unfold a list of choices, then click Edit as shown below:

11-MyConApp-properties-page-4.PNG

Then Precompiled Header Output File dialog box opens, see below:

11-MyConApp-properties-page-5.PNG

Change $(IntDir)$(TargetName).pch to $(IntDir)$(TargetName)_$(PlatformTarget).pch, see below. Please note that $(PlatformTarget) Visual C++ macro is expanded as x86 in the picture below (red box). Then click OK button to accept the changes.

11-MyConApp-properties-page-7.PNG

The changes we’ve made to the Precompiled Header setting for the project should look as below:

12-MyConApp-properties-page.PNG

STEP 4. Do not click OK button yet, instead click Apply button, after which click stdafx.cpp in the Solution Explorer as shown below. If you already clicked OK button, you can open this Property Pages dialog box again by right-clicking stdafx.cpp in the Solution Explorer, selecting Properties in the context menu as shown below:

13-stdafx-cpp-properties-page-0.PNG

Then we have stdafx.cpp Property Pages open, in which select Configuration Properties, C/C++, Precompiled Headers in the left-hand side, if not yet selected.

13-stdafx-cpp-properties-page-1.PNG

(To view big image, right-click the picture and select Open image in new tab)

Please note Use (/Yu) is selected for Precompiled Header option enclosed in the blue rectangle in the figure above. We have to change it to Create (/Yc) for stdafx.cpp. See the pictures below:

13-stdafx-cpp-properties-page-2.PNG

(To view big image, right-click the picture and select Open image in new tab)

13-stdafx-cpp-properties-page-3.PNG

Now click OK to close this (stdafx.cpp Property Pages) dialog box. If stdafx.cpp is not open in the editor, open it by double-clicking stdafx.cpp in the Solution Explorer, type in #include "stdafx.h" as shown below, then save all documents by pressing Ctrl+Shift+S keyboard combination:

 14-stdafx-cpp-first-line.PNG

Now double-click stdafx.h in the Solution Explorer to open it in the editor. Type in #pragma once, then press Ctrl+Shift+S to save all changed files.

14-stdafx-header-first-line.PNG

When you are using precompiled header files feature in Visual C++, all source code files (*.cpp) should begin with #include "stdafx.h" preprocessor directive, and all header files (*.h) should begin with #pragma once preprocessor directive.

STEP 5. Now we will add our custom C++ class, CMyObject, to our project. We can add header file MyObject.h and source code file MyObject.cpp separately, but we can add both files to our project by adding the class. In the Solution Explorer, right-click the project file MyConApp, select Add, Class… in sequence as shown below:

15-project-add-class.PNG

Or we can do the same in the Class View.

16-class-view-add-class.PNG

In the Class View, right-click MyConApp, select Add, Class… in sequence. In either way, we will have Add Class - ProjectName, where our ProjectName is MyConApp. If Class View is not open in Visual Studio, we can open it by Ctrl+Shift+C keyboard combination.

17-project-add-class.PNG

In the left-hand side, click Installed, Visual C++, C++ in sequence, if not yet selected. Select C++ Class, then click Add button at the bottom right corner (see above). We now have Generic C++ Class Wizard open as below:

18-generic_cpp-class-wizard.PNG

Type CMyObject in the Class name: field, accept the rest and click Finish to close this dialog box. Now MyObject.h is added to Header Files folder and MyObject.cpp to Source Files folder respectively. Press Ctrl+Shift+S keyboard combination to save all files. See the screenshot below:

Before we move to the next step, let’s examine Precompiled Header Files option for newly added MyObject.cpp. This is source code file (*.cpp). Any source code file should have .cpp file extension. To use Precompiled Header Files feature, any source code file should have #include "stdafx.h" as its very first line of code (it does not need to be in line# 1 as long as it is the first code line in the file). Indeed, in the picture above, the first line of code is #include "stdafx.h." In the picture below, MyObject.cpp Property Pages dialog box, Precompiled Header option is set to Use (/Yu), which is correct for any cpp source file that is to use precompiled header feature.

 

STEP 6. Now we will add source.cpp, in which it will contain main() function, to our project MyConApp. In the Solution Explorer, if not yet open, press Ctrl+Shift+L to open it, right-click Source Files folder, select Add, New Item... in the context menu. See below:

Add New Item dialog box opens, in which select Installed, Visual C++, Code in the left-hand side, if not selected yet. Select C++ File (.cpp) in the middle, type Source.cpp in the Name: field, then click Add button at the bottom right corner. See below:

Source.cpp will be added and open in the editor as shown below:

In the Solution Explorer, right-click Source.cpp, select Properties in the context menu as below:

20-source-files-add-new-item-4.PNG

Which opens Source.cpp Property Pages dialog box, in which Use (/Yu) is already selected as Precompiled Header option. This property setting is inherited from the project setting we have previously done in STEP 3. Click OK to close this dialog box.

20-source-files-properties.PNG

In the Source.cpp file, the first line of C++ code should be #include "stdafx.h", type in #include "stdafx.h" as shown below. Every and each C++ source code file (*.cpp) must have #include "stdafx.h" as its first line of code in it. This code line can be in the first, second, third, or whatsoever line, but should be the first code text in it.

 

Every and each C++ header file (*.h) should have #pragma once preprocessor directive as its the first line of code in it. We have two header files, stdafx.h and MyObject.h in our project. They both have #pragma once as their first line of code in them. See below:

Make changes to MyObject.h and MyObject.cpp as shown below. If not open yet, double-click each file in the Solution Explorer to open them in the editor. After modifying them, don’t fail to press Ctrl+Shift-S keyboard combination to save all changes.

23-myobject-header-code.PNG

(To view big image, right-click the picture and select Open image in new tab)

If you cannot layout the editor windows as in the above picture, don’t bother now. If you watch YouTube video, it’s just a piece of cake. Now open stdafx.h file in the editor. If not yet open, double-click stdafx.h in Header Files folder of the Solution Explorer, then modify this file as in the screenshot below:

 

C++ standard header file, iostream, is included using #include preprocessor directive. Please note that we should include C++ standard library header file such as iostream, cstdio, or any system include header files, such as windows.h, atlbase.h, etc, and those header files that do NOT change often between compilation processes. If we include our own custom header files, i.e., the header files that are frequently changed while developing cycle, the sole purpose of Precompiled Header files would be beaten or meaningless for they have to be frequently compiled each time the included header is changed. Press Ctrl+Shift+S again to save all changes. Now double-click Source.cpp from Source Files folder of the Solution Explorer to open it in the editor, and make changes as shown below:

Again the first line of code is #include "stdafx.h", and we also included MyObject.h using #include "MyObject.h" preprocessor directive. Add more code lines as shown below:

After modifying the file, press Ctrl+Shift+S key combinations to save all changes.

STEP 7. Building application solution is a very CPU intensive task. Always save all files with Ctrl+Shift+S key press before compiling. To build and run the application, either select Debug, Start Without Debugging (Ctrl+F5) or Start Debugging (F5) from main menu bar.


If no bug, it will be compiled/linked and executed in sequence. If Microsoft Visual Studio - This project is out of date dialog box opens and ask you Would you like to build it? Click Yes.

If no bug, the solution will be built successfully and executed as below:

To recap what we’ve learned so far, we have changed Precompiled Header setting for the project MyConApp as Use (/Yu), and for Precompiled Header Output File option, we have changed from $(IntDir)$(TargetName).pch to $(IntDir)$(TargetName)_$(PlatformTarget).pch, where $(TargetName) expands to MyConApp, and $(PlatformTarget) expands either to x86 (for 32-bit windows application) or x64 (64-bit application) depending on target platform.

(To view big image, right-click the picture and select Open image in new tab)

We have also changed Precompiled Header setting for stdafx.cpp to Create (/Yu) as below:

(To view big image, right-click the picture and select Open image in new tab)

We have added MyObject.h, MyObject.cpp, and Source.cpp AFTER we had made changes to the project settings, because we wanted to inherit the project settings to our other custom header files and source code files, such that the Precompiled Header options for MyObject.cpp and Source.cpp are automatically set properly by inheriting them from the project settings, when we added them to our project MyConApp, as below:

I have created PrecompiledHeaderSolution in the D:\DevSoft\VisualStudio2015\TutorialProjects folder.

The default Visual C++ project folder is ..\Document\Visual Studio 2015\Projects folder.

In this folder, we can find PrecompiledHeaderSolution, and its subfolder, MyConApp\Debug, then we can find MyConApp_x86.pch in it, see below:

This file MyConApp_x86.pch is the precompiled header files’ database in Win32 or 32-bit platform. The macro $(IntDir)$(TargetName)_$(PlatformTarget).pch, which we previously set in STEP 3, is expanded to MyConApp_x86.pch.

STEP 8. We will now build 64-bit application. In the Visual Studio again, if we open project MyConApp’s Property Pages dialog box again, and select x64 from Platforms, we can find that $(IntDir)$(TargetName)_$(PlatformTarget).pch would expand to MyConApp_x64.pch, as shown below.

36-MyConApp_x64-pch.PNG

(To view big image, right-click the picture and select Open image in new tab)

In Visual Studio, select x64 in the Platform dropdown box as shown below:

(To view big image, right-click the picture and select Open image in new tab)

Now press Ctrl+F5 to build and run 64-bit application. If no error, we will have the screenshot below:

This result is the same as we have done in x84 (or 32-bit build), but it is 64-bit application, not 32-bit.

If we fire up Windows File Explorer, and move to

..\PrecompiledHeaderSolution\MyConApp\x64\Debug

or to

        ..\PrecompiledHeaderSolution\MyConApp\x64\Release

We can find MyConApp_x64.pch, the 64-bit precompiled header files’ database.

Please watch YouTube video, and leave your comment. Thank you for reading a very boring document. For more information about Precompiled Header files, please refer to Microsoft MSDN documentation.

Author: Chang Hee Kim, As.G. Thomas Kim

http://www.TalkPlayFun.com

http://www.TranslatorsFrom.Asia

Original Edit: Feb. 10, 2017