How to Avoid Precompiled Headers

How to avoid precompiled headers

You can always disable the use of pre-compiled headers in the project settings.

Instructions for VS 2010 (should be similar for other versions of VS):

Select your project, use the "Project -> Properties" menu and go to the "Configuration Properties -> C/C++ -> Precompiled Headers" section, then change the "Precompiled Header" setting to "Not Using Precompiled Headers" option.


If you are only trying to setup a minimal Visual Studio project for simple C++ command-line programs (such as those developed in introductory C++ programming classes), you can create an empty C++ project.

Why can't I disable the use of precompiled headers in Visual Studio?

Sometimes you can spend hours scratching your head over something that has a very basic solution. In this case, the Active configuration was Debug, but I was changing the Precompiled Header option for the Release configuration. When I changed the option in the Debug configuration, voila! no more errors.

Precompiled headers - necessary to remove all precompiled headers from all other files

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.

C++ Precompiled Header Disabled

Ok. Hans Passant found out what was happening:

The build configuration that I used to build it still had precompiled headers enabled.

How to disable precompiled headers with msbuild?

We can't directly do this by msbuild since PrecompiledHeader is not a msbuild property...

MSbuild reads data from project file to execute the build. And there're several elements in xx.vcxproj can be specified in command-line like targets, properties, so we can use command like msbuild xx.vcxproj/xx.sln /t:xx /p:xx to specify the target element and property element when building in command-line.

e.g: msbuild xx.vcxproj /t:build /p:OutDir=xxx can specify where to output your assembly.

I changed one VS2015 C++ project's settings to make it not use precompiled headers, after comparing the difference(using git for version control) between the two versions of the xx.vcxproj file I found:

Sample Image

So the element to control the behavior of precompiled-header is an Item metadata in ClCompile Item. Since the element is an Item metadata instead of a property, we can't use command like msbuild xx.vcxproj /p:PrecompiledHeader=NotUsing ... to disable the precompiled headers. (/p <=> /property)

Possible direction:

The only possible direction I can imagine which may work to achieve your goals is creating a custom property to control this behavior.

1.For a normal C++ project, the content of its project file is:

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
...
</ClCompile>
</ItemDefinitionGroup>

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
...
</ClCompile>
</ItemDefinitionGroup>

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
...
</ClCompile>
</ItemDefinitionGroup>

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
...
</ClCompile>
</ItemDefinitionGroup>

2.Add a custom DisablePCH property, make a copy of these four ItemDefinitionGroups and involve this property into their Condition.

<PropertyGroup>
<DisablePCH>false</DisablePCH>
</PropertyGroup>

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32' And '$(DisablePCH)'=='false'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
...
</ClCompile>
</ItemDefinitionGroup>

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64' And '$(DisablePCH)'=='false'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
...
</ClCompile>
</ItemDefinitionGroup>

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32' And '$(DisablePCH)'=='false'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
...
</ClCompile>
</ItemDefinitionGroup>

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64' And '$(DisablePCH)'=='false'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
...
</ClCompile>
</ItemDefinitionGroup>

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32' And '$(DisablePCH)'=='true'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
...
</ClCompile>
</ItemDefinitionGroup>

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64' And '$(DisablePCH)'=='true'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
...
</ClCompile>
</ItemDefinitionGroup>

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32' And '$(DisablePCH)'=='true'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
...
</ClCompile>
</ItemDefinitionGroup>

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64' And '$(DisablePCH)'=='true'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
...
</ClCompile>
</ItemDefinitionGroup>

3.Then by default if we use normal command like msbuild xx.vcxproj ... , it will use the precompiledheaders. If we want to disable it in command, use command like msbuild xx.vcxproj /p:DisablePCH=true ....

ps:If you do want to disable PCH(precompiled headers) by msbuild, you can try the possible direction, for some reason I'm not able to test it in my machine :(. Feel free to let me know if it helps or not.

When do i want to turn off precompiled header in visual studio?

Originally a comment, but I may as well post it. Note: this is specific to VC++:

  1. 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.

  2. 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.

  3. You typically use a source/header pair to generate "the One"; the precompiled header image. This header file typically includes:

    1. Any system standard lib headers used by your project
    2. 3rd-party SDK headers
    3. 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.

Can't disable precompiled headers for single C file in VS2015

I found a workaround to make the right tool I needed appear... I leave it here as an answer in case someone else encounters this problem.

It won't appear by clicking file -> Properties, but it appears when clicking project -> Properties so, once opened, I selected the file autofit.c from the tree view and finally I could disable precompiled headers from this single file !

Sample Image

Precompiled header problems

Your problems have nothing to do with precompiled headers. A good practice is to include all the stuff directly used by current file. This will prevent changes in includes of one header file from potentially requiring changes in includes in files that are using this header. vector needs to be included in ABC.h because it is directly used there. Otherwise you'll end up with endless struggling to figure out which headers needs to be included when including this particular library header.

Precompiled headers and normal includes

No

(In general). What's going to happen is that, during compilation, if you're using precompiled headers, and the compiler spots a header that is already present in the precompiled form, it will opt to use the precompiled form.

In fact, it's good practice to continue using your includes as if you never had precompiled headers on in the first place. This helps in case you turn off precompiled headers in the future or modify the list of headers in it, or someone else decides to do their own out-of-source build that doesn't use PCH.



Related Topics



Leave a reply



Submit