|
Boost : |
Subject: Re: [boost] [modularization] What do we do with "glue" headers?
From: Daniel Pfeifer (daniel_at_[hidden])
Date: 2013-10-19 09:58:35
2013/10/19 Andrey Semashev <andrey.semashev_at_[hidden]>:
> On Saturday 19 October 2013 11:22:58 John Maddock wrote:
>> Trying to get this discussion somewhat back on track...
>>
>> There are many libraries in Boost that have "glue" headers: by this I mean
>> small headers that allow library A to interoperate with library B. Often
>> these are simply specializations of traits classes or function overloads,
>> are relatively trivial, and are not included unless you need them to be. By
>> this I mean that: suppose library B wants to interoperate with lib A. It
>> defines a special header which #includes what it needs from lib A and
>> defines whatever specializations are required to get the two libraries
>> working together.
>>
>> Now here's the thing: there is no dependency from lib B to lib A *unless you
>> are already using both libraries*.
>>
>> A good example would be the serialization lib: a simple dependency tracker
>> would show this up as a dependency to a large part of Boost, but in fact
>> that's not true: in the vast majority of those cases there is no such
>> dependency unless you actually want to use both libraries together and do so
>> by including the "glue" header.
>>
>> So where does the glue header belong?
>>
>> In most cases if you want B to interoperate with A then you define a header
>> which:
>>
>> * Includes headers from both libraries.
>> * Uses the public interface of A, but may access the internals of B (think
>> serialization).
>>
>> Which would imply that the header belongs with B. Pure and simple. Except
>> it's not, because these two libraries may be peers, and interoperability may
>> be more complex than simply unidirectional.
>>
>> I don't have an answer here, but it seems to me that "dependency" is a more
>> complex thing than simply what-includes-what (and that's without getting
>> into header file, vs source file, vs test file dependencies).
>
> I think a notion of an optional dependency is needed. I don't know how such
> dependencies should be expresses in the technical sense though. Ideally, ryppl
> (or whatever other dependency tracking system) should offer a way to select
> the dependencies to install.
I agree.
Lets use the example of Boost.UUID and Boost.Serialization.
My gut-feeling says that serialization support for UUID belongs to
UUID. But lets consider the alternatives:
If serialization support for all libraries belongs to Serialization,
the Serialization library is required to keep serialization support
updated for all current and future Boost libraries.
If we say the glue code shall be a distinct component, we and up with
an explosion of glue-components, one for each edge in the worst case.
So, having serialization support as an optional part of the supported
components seems most viable.
Simply scanning all headers for #includes gives a list of all possible
dependencies. Telling whether such a dependency is actually required
or just optional cannot be easily decided.
A smarter dependency scanner might be able to distinguish optional
dependencies for libraries that provide an "include all" header.
Example:
"boost/asio.hpp" pulls in most headers from Boost.ASIO, but not all.
"boost/asio/ssl.hpp" is an example of such an exception.
Hence, SSL is an optional dependency of Boost.ASIO.
cheers, Daniel
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk