3
votes

CMake 3.18; VS 2019;

I'm learning CMake and to check my results I'm trying to generate visual studio project. My current problem is precompiled header option. What I want to achieve is that VS project will have "/use" or "/create" precompiled headers option with correct file name.

In my project folder I already have ugpch.h & ugpch.cpp files, which stands for precompiled headers. I've tryied to use target_precompile_headers(UGame PRIVATE Source/ugpch.h) instruction in my cmakelists, but that has no effect on my visual studio precompiled header option. What is the correct way to do this?

Edit: I've updated my cmake to 3.18 version, but still no effect that I expected in my generated visual studio project. Instead I found new folder "Precompile header files" with cmake_pch.cxx file.. It looks like target_precompile_headers did something totally different from what I expected

2
Can you show the rest of your CMake file? Also, is the file path and file name correct? You mention you created pch.h but your CMake command specifies the file as Source/ugpch.h... - squareskittles
Here is the documentation for target_precompile_headers. See that CMake generates the PCH files for you. - squareskittles
@squareskittles thanks for pointing out, I've corrected my spelling issue, but still no effect - Araxnid

2 Answers

6
votes

The command target_precompile_headers has been added in CMake 3.16.

You'll either have to upgrade your CMake distribution (The one shipped inside VS2019 is quite up to date) or install the latest from the installer.

Otherwise, you'll have to use cotire for precompiled header, but my recommendation would be to upgrade since it's usually quite easy to do, and you probably already have an up to date version on your computer shipped with visual studio.


Since you updated your question.

The command target_precompile_headers is not doing what you think. You don't provide your PCH there, you provide what header should be part of the generated PCH. If the file ugpch.h contains includes for headera.h, headerb.h and headerc.h, then your precompiled header command should look like this:

target_precompile_headers(UGame PRIVATE headera.h headerb.h headerc.h)

The actual precompiled header will be generated by CMake.

Of course, you can still use ugpch.h as your precompiled header. CMake will simply use it to generate its own. As you observed.

After that, remove manual inclusion of the header. It will be included automatically.

From the CMake documentation:

The list of header files is used to generate a header file named cmake_pch.h|xx which is used to generate the precompiled header file (.pch, .gch, .pchi) artifact. The cmake_pch.h|xx header file will be force included (-include for GCC, /FI for MSVC) to all source files, so sources do not need to have #include "pch.h".

Why does it work like that you ask? CMake support PUBLIC precompiled header. If you link to multiple target that each have public precompiled headers, then your target inherit all of them. Since compilers usually accept one precompiled header, CMake has to generate agglomerated headers for that to work.

1
votes

Using an older version of cmake... i've used the /Yc and /Yu compiler flag with visual studio. It is not as universal as target_precompile_headers(UGame PRIVATE Source/ugpch.h) but should do the trick :)