Boost logo

Boost :

From: Deniz Bahadir (deniz.bahadir_at_[hidden])
Date: 2021-06-11 14:20:51

Am 11.06.21 um 11:17 schrieb Rainer Deyke via Boost:
> On 10.06.21 23:36, Andrey Semashev via Boost wrote:
>> On 6/9/21 2:05 PM, Rainer Deyke via Boost wrote:
>>> On 08.06.21 09:33, Gavin Lambert via Boost wrote:
>>>> 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.
> If this functionality works the way I think does, then I think it
> should not be used.

And in what way do you think it works? (Honest question.)

>> 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.
> Actually, the standard library is a great example of what I am talking
> about.  A header-only library (B) should not care about the specific
> implementation of the standard library (A) being used by the program
> (P).  There is no link dependency from B to A.  There is a requirement
> from B to P that P must provide /a/ implementation of the C++ standard
> library, but B doesn't care if it is libstdc++ or libc++ or even a
> custom standard library implementation that is part of P and not a
> separate library at all.

That works for the standard-library, because you can be sure that one is
available. (Otherwise your C++ compiler would be broken.)
However, for other libraries A there is no way to guarantee that.

Of course, you need to make sure that (any) dependency A is available on
your build machine, otherwise building could never succeed. But the
extra burden, to prepare the build-files (aka CMakeLists.txt) of your
program P to find and explicitly configure even indirect dependencies
(using `find_package`, `target_link_libraries`,
`target_include_directories` etc.) is not to be underestimated.
For a complex dependency-hierarchy this can become a nightmare, in
particular if you need to find out in what order to process the
individual build-files (`add_subdirectories`, `find_package` etc.).

Instead, program P should only be expected to declare its direct
dependencies (using `target_link_libraries`) and automatically get all
the usage-requirements (aka dependencies) of these. This only requires,
that every dependency (CMake target) carries its own usage-requirements.
And, IMO, this should be true for header-only CMake targets, too.

> Again, to make my point absolutely clear: header-only library B
> "using" library A does not imply a dependency from B to A. Instead, it
> implies a requirement on a program P that uses B to also link to A. 
> Header-only libraries use interfaces.  Programs link to implementations.
I just want to emphasize that even such interfaces are part of the
usage-requirements I was talking about.
Therefore B has a **usage-dependency** on A. And the CMake target for B
should communicate this (through its usage-requirements) to its user,
the program P (or more specific its CMake target).

The usage-requirements of the CMake target for B will become the
build-requirements of the CMake target for P (and could possibly even
become its usage-requirements as well).

And whether A is header-only or not is irrelevant. This (indirect)
dependency from P to A can either mean linking against A or just having
the correct include-search-path for the headers of A.
The CMakeLists.txt file for building P needs to have this information
either way. And this can be provided explicitly (as you prefer) which
can become quite complex and tedious, or automatically and indirectly
through B.


PS: Maybe watching the first 11 minutes of my CMake talk [1] from
Meeting C++ 2018 might help to better understand this target-centric
approach CMake took.


Dipl.-Inform. Deniz Bahadir
Reuchlinstr. 10 D
10553 Berlin
Phone: +49 - 30 / 577 0004-22
Email: deniz.bahadir_at_[hidden]
Board of Management: Stephan Schroeder, Dr.-Ing. Ingmar Poese
Commercial Register: Amtsgericht Bonn HRB 19378

Boost list run by bdawes at, gregod at, cpdaniel at, john at