0

I am working with a codebase containing classes shared between multiple projects. Until now those classes had simply been stored in common folders and referenced in-place. In the interest of versioning these dependencies, I've started grouping them into Conan packages and using CMake.

Before this effort, each project had a stdafx.h which contained everything needed by that project and whatever shared classes it used. Now, I am trying to create a precompiled header for each Conan package, so they build independently.

The hiccup is the following scenario:

ClassA.h

//If I don't include LibraryPrecompiledHeader.h here or in example.cpp, 
//the method signature below will not compile.

class ClassA
{
public:
    HRESULT Method1(LPCTSTR str);
};

ClassA.cpp

#include "LibraryPrecompiledHeader.h"
...

LibraryPrecompiledHeader.h

#pragma once

#include <atlstr.h>
#include <atlcoll.h>

Example.cpp (Conan test class consuming the library)

#include "LibraryPrecompiledHeader.h" //It will not build without including this here
                                      //or in ClassA.h
#include "ClassA.h"
...

I can think of several ways to make this work, none of which I like:

  1. Include LibraryPrecompiledHeader.h in Example.cpp. That would mean any consumer of the library would have to do the same every time a class from the library is needed.
  2. Include LibraryPrecompiledHeader.h in the ClassA.h. This has yielded conflicts later when a project uses multiple packages, each with their own precompiled headers. Specifically, I'm running into an issue of windows.h being included multiple times by various ATL & MFC headers.

Update: This problem is not specific to pre-compiled headers. If I simply include atlstr.h directly, I still must include it in either ClassA.h or example.cpp. It turns out MFC & ATL are both trying to pull in Windows.h. The MFC includes must come first to avoid the windows.h double include, which is difficult to guarantee if each package only includes what it needs.

  1. Create One-Precompiled-Header-To-Rule-Them-All and use it everywhere. This means having a huge precompiled header included on even the smallest of libraries.
  2. Include the dependencies for the library in the precompiled header of the class that eventually consumes them. This tightly couples the consumer to the library implementation.

Is there something I am missing?

Ðаn
  • 10,934
  • 11
  • 59
  • 95
Joe Schrag
  • 855
  • 8
  • 23
  • 1
    I don't fully understand the use case. Precompiled headers are a build optimization, do you mean that you want to package pre-compiled headers stuff (like the .pch from compiling stdafx.cpp) in the Conan packages? – drodri Mar 25 '20 at 17:50
  • 1
    IMHO, I recommend not using precompiled headers. Long time ago when large builds took hours, precompiled headers saved a lot of time. In modern times, they can actually cause builds to take longer (ex. if any header file in the precompiled set changes, all the headers have to be recompiled). They also add additional complexities, such as your situation. Only worry about precompiled headers when your builds or client builds are measured in hours. – Thomas Matthews Mar 25 '20 at 17:50
  • Let me add that there is no standard format for precompiled headers, nor is there a standard requirement for all compilers to support precompiled headers. – Thomas Matthews Mar 25 '20 at 17:51
  • @dodri That is what I am going for. Though, given my limited knowledge of the intricacies of the compilation process, that may be completely misguided. – Joe Schrag Mar 25 '20 at 18:05
  • 1
    @JoeSchrag seems an extremely unusual case. So far nobody has done that. Conan might be capable, because it can create a different package per configuration, so even if the .pch is different format for different compilers, it might work. However, probably is not worth, given the peculiarities of pre-compiled headers, unless you are talking about packages that take many hours of building and you proof that a very big chunk of that time is due to the headers. – drodri Mar 25 '20 at 22:44
  • @drodri Haha. "So far nobody has done that." That's never a good sign. I'll seriously evaluate whether we need pre-compilation. Also, I've found that the root cause of my windows.h include problem is that the project is using both MFC & ATL. For reasons still undiscovered, it builds in the old MSBuild project, but not in CMake. I'll bang my head against that for a while and open a different question if I don't succeed. – Joe Schrag Mar 25 '20 at 23:58

0 Answers0