I've done a study and written some tools, to determine just how many Boost header files must be included to use some of the Boost modules. The numbers are staggering:
...
This is a legitimate concern which IMO has not been taken seriously by the Boost community.
Why do you think this is not being taken seriously? I'm under the impression that there is disagreement as to the real priority of this concern. I think that is quite different. I know I put forward several points that may well be perceived as not taking this seriously. I was genuinely asking why the OP cared about the number of included header files. As a technical question I still find it puzzling to find this a development priority since the solutions involve considerable development effort and a combinatorial explosion in deployed configurations. For these disadvantages, if I am to spend time reducing header file dependencies I require a good reason for expending this effort. Most arguments about this have centered around satisfying an existing arbitrary rule in other organisations. While I sympathise with the developers having to deal with these organisations, it is not compelling to prioritise this issue over and above the work I would be doing to extend Boost.Range or deal with trac tickets.
To some extent it's unavoidable since it's more efficcient to have one "best" solution imported everywhere rather than replecating code.
But it doesn't have to be as bad as it currently is. And it's only getting worse as more libraries get added to Boost.
Again why is it 'Bad'? This is re-use in most examples I have seen. Coupling isn't inherently bad. Re-use is coupling. Specific examples of poor coupling most probably exist. I suspect these would receive a good response from the Boost development community if these were specifically raised.
Here's what I suggest for boost users such as yourself:
a) don't use "convenience headers" which suck in all the headers in a library rather than just the one's used. It seems tedious because one has to read more carefully to know which headers to use but it saves huge amounts of build time and diminishes "dependency surprises" which can cost a lot of time to track down.
+1 - Definitely good advice. We Boost developers should provide the option for the users to make their own choice with respect to having a simple easy to remember include path with slower compile-times, or more specific includes. I believe we do that well.
b) a few libraries "infect" your code with "spreading" depencies. Use your analysis to detect these libraries and complain about them. I have done this in the past to no effect. It did make me feel I was doing something though. If you can't get library authors to see this, you'll just have to avoid that library or fork your own copy.
Did you complain about them in trac tickets that have not been resolved? I definitely am guilty of recently having poor response times to trac tickets. This is something which I would like to assist in getting resolved. Of course, if the library maintainer disagrees that the header file inclusion or dependency is 'bad' then the usual rules apply that the maintainer has the final say. The benefit of avoiding design by committee comes at the cost of some disagreement.
c) In your own code, use pre-compiled headers. This speeds up re-builds. It DOES force you to spend some time looking at how you've divided up your own code but this time is a good investment.
I'm personally undecided about pre-compiled headers. I find this normally means that one has considerably increased the amount of included code per translation unit and therefore generated additional coupling that is far more significant than the perhaps sub-optimal inclusions within Boost.
Here's what I suggest library author's do:
a) Take this gentlement's complaint seriously.
I would be surprised if any of the Boost developers didn't take this seriously. My perception is that many of us are not convinced this is a priority. That isn't the same thing.
b) Consider eliminating "convenience" headers.
I think the Boost library authors are good at choosing the right level of headers to include. Do you have some specific counter-examples?
c) When writing documentation avoid depence on "convenience headers". This seems like it adds some work - less conveniece - but hels addressing this man's problem.
I definitely took the approach of using convenience headers in examples. I did this because the header files were not the primary focus of the example code. The convenience header in my examples provides code that works while reducing clutter in my example. I therefore disagree that we should have a policy of avoiding the convenience headers. Perhaps instead we could provide additional guidance as to how to use the layers of header files. However this seems trivially obvious.
Here's what Boost can do. Something like:
a) Formalize the comcept of boost library "levels" i) core - e.g. config, auto-link, BOOST_NONCOPIABLE, ... ii) utility - e.g. scoped_ptr, ... iii) application support - e.g serialization
Layering the libraries is a good idea. It would appear to be the only manageable way of providing more deployment componentisation in sensible number of tested cohesive units.
Every boost component would depend only on components at the same or lower level. The assignment of library level would be part of the review process.
The motivation here is to support the future growth of Boost and C++ libraries in general. I see this as the fundamental requirement behind any efforts to achive "Boost Modularization"
Robert Ramey
Neil Groves