Re: [boost] CMake, modular Boost, and other stories
Hmmm - so no boost library should include any other boost library? Does that seem a good idea? Please don't put words in my mouth. I didn't say that and you know it. But the dependency graph could easily be significantly simplified once c++03 is no longer a concern. Again: I'm talking about the future, not the current state. Just an example: [1]Boost.TypeErasure depends on [2]Boost.Thread(and all that entails), just because somewhere in its bowels it needs a mutex. It's always been good practice to not repeat/copy functionality in one library into another. Not always. A recent example I stumbled over: Boost.Signal2 depended on boost multi index (which itself depends on a lot of other libs) because it reused it's scope guard implementation (IIRC about 50 lines of straight forward code). Tying yourself to another library for something trivial like that should not be a no-brainer. But what is really needed - and it may already exist in BCP but hasn't been promoted is a simple tool: a) start with one's application b) run the app through a tool which recurrsively reads headers c) and creates a list of all headers needed d) extract library names from that list e) add the git repo of those libraries to my apps project. So boost should not only get its unique build system, but also its unique dependency management tool? I can tell you as a user: Thanks but no thanks. Also: Didn't you forget source files somewhere in there? What about tests? Bottom line: If boost as a whole was developed as a single project with some coordinated devlopment goal and strategy , it would make sense to distribute it as a single package/framework and a single cmake config file. It seems to me however, that it is more a (huge) collection of independently developed libraries, so I think it is more appropriate to treat them as such, even if there is a huge amount of coupling between them.
Am 23.04.19, 23:56, Robert Ramey via Boost
On Wed, Apr 24, 2019 at 9:12 AM Mike via Boost
It's always been good practice to not repeat/copy functionality in one library into another. Not always. A recent example I stumbled over: Boost.Signal2 depended on boost multi index (which itself depends on a lot of other libs) because it reused it's scope guard implementation (IIRC about 50 lines of straight forward code). Tying yourself to another library for something
[...] Just an example: [1]Boost.TypeErasure depends on [2]Boost.Thread(and all that entails), just because somewhere in its bowels it needs a mutex. trivial like that should not be a no-brainer.
As Rene mentioned, cycles are bad, and should be eliminated. But Mike is also right in that not all (non-cyclic) dependencies are desired, especially those that are "small", yet carry "lots of baggage". Perhaps it's something that's missing from the current dependency analysis, the "surface area" of the dependency, and whether it's for the public APIs or an implementation detail, so that those can be pushed down to a lower-level library and thus eliminate dependencies between "lightly coupled" libraries. Is it something doable, to have such an analysis? But this is a bit OT with Peter's original post of course. At work we bring in the whole of Boost as a "3rd party" dependency, and declare dependencies per-libraries using the equivalent of the latter method. But I can see the appeal of the former as well, especially if there's a precedent with vcpkg and conan, especially when wanting to promote modular Boost. If both methods are already available, why should Boost limit the choice of the "consumers"? Unless those doing the work think maintaining both is a big burden, I'd keep the latter to maintain consistency with the way things used to work, and provide the former as an alternative for those who prefer it. I'm not buying the CMake zealots who advocate for the "one true way" of doing it... --DD
On 24. Apr 2019, at 10:30, Dominique Devienne via Boost
wrote: As Rene mentioned, cycles are bad, and should be eliminated. But Mike is also right in that not all (non-cyclic) dependencies are desired, especially those that are "small", yet carry "lots of baggage".
Perhaps it's something that's missing from the current dependency analysis, the "surface area" of the dependency, and whether it's for the public APIs or an implementation detail, so that those can be pushed down to a lower-level library and thus eliminate dependencies between "lightly coupled" libraries.
Boost.Histogram on its release was the library at the bottom of the module level hierarchy. `boostdep --module-levels` I started to replace some of the dependencies of Boost.Histogram with private implementations, which is not really a nice solution, because it can and will introduce new bugs. Dropping boost.iterator was a big step up in the module levels, but it didn't feel right. boost.iterator is very annoying to replace and the actual core CRTP class should not depend on much else. So, it would be useful to move the actual iterator adaptors into boost.core, and have the practical iterators provided by the library with extra dependencies (function_output_iterator, shared_container_iterator, ...) stay in the library. Best regards, Hans
Dominique Devienne wrote:
I'm not buying the CMake zealots who advocate for the "one true way" of doing it... --DD
On the contrary, I wish there were more clear directions about the "one true CMake way" of doing it, because at the moment there's definite shortage and everyone seems to treat CMakeLists.txt as their own personal playgrounds.
On 4/24/19 12:12 AM, Mike via Boost wrote:
> Hmmm - so no boost library should include any > other boost library? Does that seem a good idea? Please don't put words in my mouth. I didn't say that and you know it.
Hmmm I was responding to the comment
>when I just want to use > library X, the rest of boost doesnʼt come as a > dependency with it.
I don't know any other way to read it. But the dependency graph could
easily be significantly simplified once c++03 is no longer a concern.
Hmmm I'm not sure what "no longer a concern means" in user code, in library code or ???. In any case, I don't think more/less C++03 will not affect this issue. Again: I'm talking about the
future, not the current state. Just an example: [1]Boost.TypeErasure depends on [2]Boost.Thread(and all that entails), just because somewhere in its bowels it needs a mutex. > It's always been good practice to not repeat/copy > functionality in one library into another. Not always. A recent example I stumbled over: Boost.Signal2 depended on boost multi index (which itself depends on a lot of other libs) because it reused it's scope guard implementation (IIRC about 50 lines of straight forward code). Tying yourself to another library for something trivial like that should not be a no-brainer.
> But what is really needed - and it may already exist > in BCP but hasn't been promoted is a simple tool: > a) start with one's application > b) run the app through a tool which recurrsively > reads headers > c) and creates a list of all headers needed > d) extract library names from that list > e) add the git repo of those libraries to my apps > project.
So boost should not only get its unique build system, but also its unique dependency management tool?
Such a tool would not be tied to boost. The issue of dependency affects all large programs. Such a tool as described would be useful to any large project.
I can tell you as a user: Thanks but no thanks.
LOL - Sure - it's a free country.
Also: Didn't you forget source files somewhere in there? What about tests?
The above describes the scenario in which such a tool would be used to support the tracking of dependencies in any large project. If this project was one small app - the procedure would apply to just that app. If the one wanted to includes a test suite - the procedure would be applied to the union of all the programs in the test suite.
Bottom line: If boost as a whole was developed as a single project with some coordinated devlopment goal and strategy , it would make sense to distribute it as a single package/framework and a single cmake config file.
It seems to me however, that it is more a (huge) collection of independently developed libraries, so I think it is more appropriate to treat them as such
Absolutely.
even if there is a huge amount of coupling between them.
Hmmm - this is the rub. The coupling is supposed to be narrow through type and function interfaces exposed in header code. (to a lesser extent it extends to separately compiled library code as well.) The way to deals with this is to keep the interfaces narrow. I believe that Boost libraries actually do do this. It's the framing or notion dependency in terms of library rather in therms of headers which leads us in the wrong direction.
References
Although this problem is most frequent with the serialization library, it occurs with other libraries also. In some communications, they are referred to as "glue libraries" or "bridge libraries". It might help if this notion was formalized in some way. Robert Ramey
First of all, sorry for the mess in my previous mail. I was on my mobile and the client I used has very strange ideas about formatting.
-----Original Message----- From: Boost
On Behalf Of Robert Ramey via Boost On 4/24/19 12:12 AM, Mike via Boost wrote:
> Hmmm - so no boost library should include any > other boost library? Does that seem a good idea? Please don't put words in my mouth. I didn't say that and you know it.
Hmmm I was responding to the comment
>when I just want to use > library X, the rest of boost doesnʼt come as a > dependency with it.
I don't know any other way to read it.
There is a huge difference between not wanting half/a significant portion of boost as an indirect dependency (that’s what I said) and wanting *none* of boost as an indirect dependency (that’s what you are implying I said).
But the dependency graph could easily be significantly simplified once c++03 is no longer a concern.
Hmmm I'm not sure what "no longer a concern means" in user code, in library code or ???. In any case, I don't think more/less C++03 will not affect this issue.
It means that if boost libraries no longer want concern themselves with c++03 support, then most of the dependencies on libraries like mpl, move, smart_ptr, array, variant, static_assert, bind, tuple ... and whatnot could be eliminated by using standard library types or newer (more lightweight) replacements instead.
So boost should not only get its unique build system, but also its unique dependency management tool?
Such a tool would not be tied to boost. The issue of dependency affects all large programs. Such a tool as described would be useful to any large project.
Only if you can uniquely identify an appropriate repository only based on an include statement. You can't even do that reliably in boost without first scanning all the library directories.
I can tell you as a user: Thanks but no thanks.
LOL - Sure - it's a free country.
Also: Didn't you forget source files somewhere in there? What about tests?
The above describes the scenario in which such a tool would be used to support the tracking of dependencies in any large project. If this project was one small app - the procedure would apply to just that app. If the one wanted to includes a test suite - the procedure would be applied to the union of all the programs in the test suite.
What I meant was, that only tracking along transitive header includes is not enough. As soon as you include a single header file from library A, you also have to consider *all* the source files of A.
even if there is a huge amount of coupling between them.
Hmmm - this is the rub. The coupling is supposed to be narrow through type and function interfaces exposed in header code. (to a lesser extent it extends to separately compiled library code as well.) The way to deals with this is to keep the interfaces narrow. I believe that Boost libraries actually do do this. It's the framing or notion dependency in terms of library rather in therms of headers which leads us in the wrong direction.
What I meant was plain and simple that there are a lot of dependencies between different boost libraries regardless of what definition of "dependency" you are using. You can use my BoostDepGraph utility from https://github.com/Mike-Devel/boost_dep_graph to show you only the dependency tree from a specific boost library based on tracking transitive includes of individual headers. More often than not, the tree is still huge and full of libraries that would not be necessary in a post c++03 codebase. Btw.: Serialization is imho not the problem here. If you remove it from the dependency graph, the overall situation improves only marginally (but still noticeable).
participants (6)
-
Dominique Devienne
-
Hans Dembinski
-
Mike
-
mike.dev@gmx.de
-
Peter Dimov
-
Robert Ramey