{"id":19935,"date":"2018-07-05T15:13:51","date_gmt":"2018-07-05T22:13:51","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/?p=19935"},"modified":"2024-06-20T11:42:13","modified_gmt":"2024-06-20T11:42:13","slug":"shared-pch-usage-sample-in-visual-studio","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/shared-pch-usage-sample-in-visual-studio\/","title":{"rendered":"Shared PCH usage sample in Visual Studio"},"content":{"rendered":"<p><span >This post was written by Olga Arkhipova and Xiang Fan<\/span><span ><\/span><\/p>\n<p><span ><span >Oftentimes, multiple projects in a Visual Studio solution use the same (or very similar) precompiled headers. As pch files are often big and building them takes a\u00a0significant amount of time, this leads to the\u00a0<\/span><span><a target=\"_blank\" href=\"https:\/\/visualstudio.uservoice.com\/forums\/121579-visual-studio-ide\/suggestions\/4931119-allow-precompiled-headers-to-be-shared-between-pro\" rel=\"noopener\">popular question<\/a><\/span><\/span><span ><span >: is it possible for several projects to\u00a0use the same pch file which would be built just once?<\/span><span style=\"margin: 0px;font-family: 'Segoe UI',sans-serif;font-size: 11.5pt\"><\/span><\/span><\/p>\n<p><span ><span >The answer is yes, but it requires a couple of tricks to satisfy cl\u2019s check that command line used for building the pch is the same as the command line used for building a source file using this pch.<\/span><\/span><\/p>\n<p><span ><span >Here is a sample solution, which has 3 projects \u2013 one (SharedPCH) is building the pch and the static library and the other two (ConsoleApplication 1 and 2) are using it. You can find the sample code source in our <a href=\"https:\/\/github.com\/Microsoft\/VCSamples\/tree\/master\/VC2017Samples\/SharedPchSample\">VCSamples GitHub repository<\/a>.<\/span><\/span><\/p>\n<p><span ><span >\u00a0<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch1.png\"><img decoding=\"async\" width=\"319\" height=\"607\" class=\"alignnone wp-image-19945\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch1.png\" \/><\/a><\/span><\/span><\/p>\n<p><span ><span >When ConsoleApplication projects reference the SharedPCH one, the build will automatically link the SharedPCH\u2019s static lib, but several project properties need to be changed as well. <\/span><\/span><\/p>\n<ol>\n<li><span ><span >C\/C++ Additional Include Directories (\/I) should contain the shared stdafx.h directory <\/span><\/span><\/li>\n<li><span ><span >C\/C++ Precompiled Header Output File (\/Fp) should be set to the shared pch file (produced by SharedPCH project)<\/span><\/span><\/li>\n<li><span ><span >If your projects are compiled with \/Zi or \/ZI (see more info about those switches at the end), the projects which use the shared pch need to copy the .pdb and .idb files produced by the shared pch project to their specific locations so the final pdb files contains pch symbols. <\/span><\/span><\/li>\n<\/ol>\n<p><span ><span >As those properties need to be changed similarly for all projects, I created the SharedPCH.props and CustomBuildStep.props files and imported them to my projects using the Property Manager tool window. <\/span><\/span><\/p>\n<p><span ><span >SharedPch.props helps with #1 and #2 and is imported in all projects. CustomBuildStep.props helps with #3 and is imported to consuming pch projects, but not to the producing one. If your projects are using \/Z7, you don\u2019t need CustomBuildStep.props.<\/span><\/span><\/p>\n<p><span ><span >\u00a0<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch2.png\"><img decoding=\"async\" width=\"355\" height=\"597\" class=\"alignnone wp-image-19955\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch2.png\" \/><\/a><\/span><\/span><\/p>\n<p><span ><span >In SharedPch.props, I defined properties for shared pch, pdb and idb files locations:<\/span><\/span><\/p>\n<p><span >\u00a0<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch3.png\"><img decoding=\"async\" width=\"514\" height=\"344\" class=\"alignnone wp-image-19965\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch3.png\" \/><\/a><\/span><\/p>\n<p><span ><span >We wanted to have all build outputs under one root folder, separate from the sources, so I redefined the Output and Intermediate directories. This is not necessary for using shared pch since it just makes experimentation easier as you can delete one folder if something goes wrong.<\/span><\/span><\/p>\n<p><span >\u00a0<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch4.png\"><img decoding=\"async\" width=\"514\" height=\"324\" class=\"alignnone wp-image-19975\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch4.png\" \/><\/a><\/span><\/p>\n<p><span ><span >Adjusted C\/C++ \u2018Additional Include Directories\u2019 and \u2018Precompiled Header Output File\u2019 properties: <\/span><\/span><\/p>\n<p><span><span><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch5.png\"><img decoding=\"async\" width=\"514\" height=\"350\" class=\"alignnone wp-image-19985\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch5.png\" \/><\/a><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch6.png\"><img decoding=\"async\" width=\"514\" height=\"350\" class=\"alignnone wp-image-19995\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch6.png\" \/><\/a><\/span><\/span><\/p>\n<p><span ><span >In CustomBuildStep.props I defined Custom Build Step to run before ClCompile target and copy the shared pch .pdb and .idb files if they are newer than the project\u2019s .pdb and .idb files. Note that we are talking about compiler intermediate pdb file here and not the final one produced by the linker. <\/span><\/span><\/p>\n<p><span ><span >If all files in the project are using one pch, that\u2019s all we need to do, since when the pch is changed, all other files need to be recompiled as well, so at the end of the build we\u2019ll have full pdb and idb files.<\/span><\/span><\/p>\n<p><span ><span >If your project uses more than one pch or contains files that are not using pch at all, you\u2019ll need to change pdb file location (\/Fd) for those files, so that it is not overridden by the shared pch pdb.<\/span><\/span><\/p>\n<p><span >\u00a0<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch7.png\"><img decoding=\"async\" width=\"514\" height=\"343\" class=\"alignnone wp-image-20005\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch7.png\" \/><\/a><\/span><\/p>\n<p><span ><span >I used the command line property editor to define the commands. Each &#8216;xcopy&#8217; command should be on its own line:<\/span><\/span><\/p>\n<p><span >\u00a0<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch8.png\"><img decoding=\"async\" width=\"514\" height=\"519\" class=\"alignnone wp-image-20015\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/spch8.png\" \/><\/a><\/span><\/p>\n<p><span ><span >Alternatively, you can put all commands in a script file and just specify it as command line.<\/span><\/span><\/p>\n<p><span ><span >\u00a0<\/span><\/span><span><span >Background information<\/span><\/span><\/p>\n<p><span><span><span><a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/reference\/z7-zi-zi-debug-information-format\">\/Z7, \/ZI and \/Zi<\/a><u> <\/u><\/span><\/span><\/span><span><span >compiler flags<\/span><\/span><\/p>\n<p><span ><span >When \/Z7 is used, the debug information (mainly type information) is stored in each OBJ file. This includes types from the header files, which means that there is a lot of duplication in case of shared headers and OBJ size can be huge. <\/span><\/span><\/p>\n<p><span ><span >When \/Zi or \/ZI is used, the debug information is stored in a compiler pdb file. In a project, the source files often use the same pdb file (this is controlled by <\/span><span><a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/reference\/fd-program-database-file-name\">\/Fd<\/a><\/span><span > compiler flag, the default value is $(IntDir)vc$(PlatformToolsetVersion).pdb), so the debug information is shared across them.<\/span><\/span><\/p>\n<p><span ><span >\/ZI will also generate an IDB file to store information related to incremental compilation to support Edit and Continue.<\/span><\/span><\/p>\n<p><span><span >Compiler PDB vs. linker PDB<\/span><\/span><\/p>\n<p><span ><span >As mentioned above, the compiler PDB is generated by \/Zi or \/ZI to store the debug information. Later, linker will generate a linker PDB by combining the information from the compiler PDB and additional debug information during linking. The linker may also remove unreferenced debug information. The name of the linker PDB is controlled by the\u00a0<\/span><span><a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/reference\/pdb-use-program-database\">\/PDB<\/a><\/span><span > linker flag. The default value is $(OutDir)$(TargetName).pdb.<\/span><\/span><\/p>\n<p><span><span >Give us your feedback!<\/span><\/span><\/p>\n<p><span ><span >Your feedback is a critical part of ensuring that we can deliver useful information and feature. For any questions, reach out to us via Twitter at <a href=\"https:\/\/twitter.com\/visualc\">@visualc<\/a> or via email at <a href=\"mailto:visualcpp@microsoft.com\">visualcpp@microsoft.com<\/a>. For any issues or suggestions, please let us know via Help &gt; Send Feedback &gt; <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/ide\/how-to-report-a-problem-with-visual-studio-2017\">Report a Problem<\/a> in the IDE.<\/span><\/span><\/p>\n<p><span ><span ><\/span><\/span><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post was written by Olga Arkhipova and Xiang Fan Oftentimes, multiple projects in a Visual Studio solution use the same (or very similar) precompiled headers. As pch files are often big and building them takes a\u00a0significant amount of time, this leads to the\u00a0popular question: is it possible for several projects to\u00a0use the same pch [&hellip;]<\/p>\n","protected":false},"author":316,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[216],"tags":[140,15,288],"class_list":["post-19935","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-documentation","tag-c","tag-pch","tag-shared-pch"],"acf":[],"blog_post_summary":"<p>This post was written by Olga Arkhipova and Xiang Fan Oftentimes, multiple projects in a Visual Studio solution use the same (or very similar) precompiled headers. As pch files are often big and building them takes a\u00a0significant amount of time, this leads to the\u00a0popular question: is it possible for several projects to\u00a0use the same pch [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/19935","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/316"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=19935"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/19935\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=19935"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=19935"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=19935"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}