Am 11.06.21 um 22:17 schrieb Rainer Deyke via Boost:
On 11.06.21 16:20, Deniz Bahadir via Boost wrote:
Am 11.06.21 um 11:17 schrieb Rainer Deyke via Boost:
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.)
I think it forces the users of library B to (indirectly) link to library A, as opposed any other library that implements the interface of A. In the worst case, it might even unnecessarily force a specific version of A.
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.
You guarantee it by documenting it as a requirement for the users of B. The human users, not CMake.
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.).
In order to build P, you need to build the specific versions of all of the libraries that P requires, with the specific build settings that P requires. The build process should never pick up random library versions found in system directories. Program P must be able to say "use this modified version of libpng instead of the upstream version", "use LibreSSL instead of OpenSSL", and "don't use zlib at all, I'll provide my own version of the zlib functions".
You can even achieve that with CMake and its target-centric approach: If library B is a good citizen it uses `find_package` to look for its dependencies (more specifically, for the CMake target of its dependencies) and provides customization points (CMake options or simple variables). So if Program P wants to force a specific version of the indirect dependency A upon B it can set these customization points beforehand or it can just call `find_package` for that indirect dependency explicitly beforehand. The later call to `find_package` from B's CMakeLists.txt should then just return the same target (without even bothering searching). Of course, this requires careful crafting of B's CMakeLists.txt. (But it really can be worth it.) In case the indirect dependency A is header-only itself, it becomes even simpler because you do not have to cope with a library that might have been compiled using different/incompatible compiler-flags. IMO, CMake is quite powerful and one can achieve some really "funky stuff". But, as always, one should remember to not make it too complex or one will be unable to find anyone else who is willing to maintain it later. Deniz -- BENOCS GmbH Dipl.-Inform. Deniz Bahadir Reuchlinstr. 10 D 10553 Berlin Germany Phone: +49 - 30 / 577 0004-22 Email: deniz.bahadir@benocs.com www.benocs.com Board of Management: Stephan Schroeder, Dr.-Ing. Ingmar Poese Commercial Register: Amtsgericht Bonn HRB 19378