| # bmcweb headers |
| |
| **Why does bmcweb use so many headers? My build times are slow!** |
| |
| TL;DR, History |
| |
| bmcweb at one point was a crow-based project. Evidence of this can still be seen |
| in the http/.hpp files that still contain references to the crow namespaces. |
| Crow makes heavy use of headers and template meta programming, and doesn't ship |
| any cpp or implementation files, choosing to put everything in include once |
| headers. As bmcweb evolved, it needed more capabilities, so the core was ported |
| to Boost Beast, and what remains has very little similarity to crow anymore. |
| Boost::beast at the time we ported took the same opinion, relying on header |
| files and almost no implementation compile units. A large amount of the compile |
| time is taken up in boost::beast template instantiations, specifically for |
| boost::beast::http::message (ie Request and Response). |
| |
| The initial solution that gets proposed is to just move everything as it exists |
| to separate compile units, making no other changes. This has been proposed and |
| implemented 3-4 times in the project, the latest of which is below. The intent |
| of this document is largely to save effort for the next person, so they can at |
| least start from the existing prior attempts. |
| |
| <https://gerrit.openbmc.org/c/openbmc/bmcweb/+/49039> |
| |
| Moving to cpp files without handling any architecture has the net result of |
| making total compilation slower, not faster, as the slowest-to-compile parts end |
| up getting compiled multiple times, then the duplicates deleted at link time. |
| This isn't great for the end result. |
| |
| To actually effect the result that we'd like to see from multiple compile units, |
| there have been proposed a few ideas might provide some relief; |
| |
| - Moving the Request and Response containers to opaque structures, so a majority |
| of code only needs to #include the interface, not any of the template code. |
| <https://gerrit.openbmc.org/c/openbmc/bmcweb/+/37445> Doing this exposed a |
| number of mediocre practices in the route handlers, where routes made copies |
| of requests/responses, relied on APIs that should've been internal, and other |
| practices that make this migration less straightforward, but is still being |
| pursued by maintainers over time. |
| - Moving the internals of Request/Response/Connection to rely on something like |
| [http::proto](https://github.com/CPPAlliance/http_proto) which, written by the |
| same author as boost::beast, claims to have significant reduction in compile |
| time templates, and might not require abstracting the Request/Response |
| objects. |
| - Reduce the bmcweb binary size to the point where link time optimization is not |
| required for most usages. About half of the bmcweb build time is spent doing |
| link time optimization, which, as of this time is required to keep bmcweb code |
| small enough to deploy on an actual BMCs (See DEVELOPING.md for details). One |
| could theoretically determine the source of where LTO decreases the binary |
| size the most, and ensure that those were all in the same compile unit, such |
| that they got optimized without requiring LTO. |