3

I do not think this is unique to my projects, it applies to any C++ library that uses precompiled headers and a project that uses the library that has its own precompiled headers. Its just that C++/winRt headers are SOOO time consuming you really need to precompile those.

I have a C++/winRT UWP library. Since it uses windows runtime APIs it 'needs' to precompile those massive header files. I call that file 'btwrpch.h' since it contains mostly Bluetooth runtime APIs. The library build fine.

Now this library is to be used in another C++/winRT UWP project which also uses windows runtimes, mostly UI stuff. The precompiled headers for this project use the classic pch.h.

To use the library, the project has the library header files including btwrpch.h. The project has its own pch.h file.

I cannot figure out how to create the precompiled headers for both.

In the project I placed the btwrpch.cpp file and the pch.cpp file. I configured each of these cpp files to generate precompiled headers.

In the project properties precompiled header option I have two files, pch.h;btwrpch.h and two output files $(IntDir)pch.pch; $(IntDir)btwrpch.pch;

Yet when I rebuild the project I get the error

fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "pch.h; btwrpch.h"' to your source?

I have one source file (in addition to the header.cpp files) called app.cpp and the two headers are included. Looking in the Debug directory, I see both pch.pch and btwrpch.pch.

What am I doing wrong?

Note if I merge the btwrpch.h file into pch.h and define only one precompiled header, it works fine. I do not want a library user to have to do that.

Brian Reinhold
  • 2,313
  • 3
  • 27
  • 46

1 Answers1

3

While you can have multiple precompiled header files per project, you can have at most one precompiled header per compilation unit. Apparently you are pulling multiple precompiled header files into a single compilation unit. This is not supported.

What am I doing wrong?

You are including precompiled header files into other headers. That is not how they are meant to be used. Include precompiled header files only ever into compilation units.

The solution here is simple: Remove all precompiled header files from your library's public interface (the header file defining the API). Instead, include all header files the library interface depends on, as if you weren't using precompiled headers at all.

When consuming this library, include the library header file into the compilation unit used to generate the precompiled header (e.g. by adding an #include "mylib.h" directive to pch.h). With that in place, both the library interface as well as all its dependencies get precompiled in the consuming project.

IInspectable
  • 46,945
  • 8
  • 85
  • 181
  • So if I understand you correctly I should take my btwrpch.h file (from the library) and inside the application project, place it in the pch.h file. Never thought of that! If you have only one file, that's a pretty neat way of solving the issue. Gotta give it a try. – Brian Reinhold Apr 16 '19 at 21:17
  • IT WORKS!! Had a few issues with a dangling semicolon I forgot to remove from the properties page but then good! – Brian Reinhold Apr 16 '19 at 21:46
  • 2
    While that works, it's not what I would recommend. Instead, make your library interface header (`lib.h`) fully self-contained, i.e. include *all* required headers right there, and only ship that header to clients. If you want to use PCHs in your library implementation, use a *private* header for that (`btwrpch.h`), which is likely going to duplicate most of the interface header's `#include` directives. This allows you to use PCHs in the implementation. A consumer of the library is still at liberty whether they want to use PCHs. If they do, they can simply include `lib.h` into their `pch.h`. – IInspectable Apr 17 '19 at 08:13