Why is my generated precompiled file so big when using a boost based library?

Viewed 282

I'm working on a project using libraries handled through vcpkg. As compile time wasn't that great, I did some headers clean up and configured the project to use precompiled headers, putting STL and vcpkg headers inside.

I started to run into the infamous C1076, C3859 and C1060 errors, and a quick check to the generated pch showed me a massive 1.2GB file ...

I ran a build using the /showIncludes switch, and it appears that spirit-po, a Boost based library that I use for translations, references more than 2600 Boost headers. (My project just has 70 files, with nothing fancy) It's the only Boost based library used in the project.

Just to be sure this was the culprit, I removed everything but the spirit-po files from the pch :

#pragma warning(push)
#pragma warning(disable : 4267)
#include <spirit_po/spirit_po.hpp>
#pragma warning(pop)

and the resulting generated file is still 1GB big ...
There's no difference in size between debug and release build.
With an empty pch file, the generated file is around 4MB.

Provided that a 250MB file is considered big, how come I end up with a file 4 times that size ?

With just that library in the pch I don't have errors compiling anymore, but I don't want the problem to arise again in the future.

I'm using Microsoft Visual Studio Community 2019 Version 16.8.4.

What are my options to improve the situation ?
Could this be a misconfiguration in Visual Studio ?
Do I have to ditch the library altogether to remove the Boost dependency ?
Is there another alternative ?

Thanks for reading me :)

2 Answers
  1. Header only libraries work because there are no details left out of those headers.

  2. Precompiled headers contain all the compiled information of the headers before start of the translation unit.

  3. A large part (the majority) of boost libraries are header only. To add insult to injury, they're highly generic meaning there will be many templates and their instantiations.

1 + 2 + 3 are the perfect storm. If the size is a concern, your better bet is to shield boost from your headers and include them in the select translation units that actively depend on them.

While doing some more research, I came across the following libraries :

  • tinygettext :
    + Doesn't depend on Boost
    - Needs Iconv library to work, which isn't that trivial to make it work on Windows even if it's available as a vcpkg package
  • spiritless_po
    + Doesn't depend on Boost
    + Self contained
    - Not compatible with spirit-po

I tested both, and I must say the last one is a perfect fit for my use, which is to use directly po files as translations ... I guess it's not a fit all solution, but it might be enough for some.

Related