On 6/9/21 2:05 PM, Rainer Deyke via Boost wrote:
On 08.06.21 09:33, Gavin Lambert via Boost wrote:
On 8/06/2021 4:53 pm, Edward Diener wrote:
I do not know CMake, so maybe my comment is irrelevant, but it seems natural to me that a header-only library would always choose to use some other dependent library as header-only, even when that other library had static or shared variants. In other words I applaud the decision of Boost.Test to provide a header-only variant and can not even begin to process the fact that CMake can not deal with Boost.Test as a header-only library, if that is indeed the case.
A problem occurs when program P uses library A as static or shared and then wants to use header-only library B which also uses library A.
For this to work, one of the following must be true: 1. library B can figure out how program P chose to link to it and links to it the exact same way.
A header-only library cannot *link* to anything, or it is not header-only.
CMake defines targets for header-only libraries, which can have dependencies on other targets, including on static or shared libraries. So the program that "links" to the header-only library picks up its dependencies recursively. As a result, the linker is invoked with all (binary) libraries in the dependency tree. Whether you can consider such library header-only in the first place is a philosophical question. I do, because otherwise any library that calls the standard library cannot be called header-only.
A header-only library B can depend on symbols being provided by the calling program P, which can delegate the task to library A, or to another library C which provides the same interface as A. There should be no direct connection from B to A. Depending on the design of B, this may involve #including a header from A before #including a header from B, or it can involve making the headers from A available to B so that B can #include them directly. Where these symbols and/or headers come from is the business of P, not of B.
Reverse dependencies are rather uncommon, and it's not what is being discussed here. The question is how the header-only library selects the targets to depend on. I think, it should not select any specific target unless it absolutely must (i.e. it won't work otherwise). In terms of the earlier example, the library B should depend on the generic target A. Now, that target A can be defined as a header-only, shared or static variant, depending on the user's choice or some default.