Home | Libraries | People | FAQ | More |
The problem with many traditional "textbook" implementations of configuration headers (where all the configuration options are in a single "monolithic" header) is that they violate certain fundamental software engineering principles which would have the effect of making boost more fragile, more difficult to maintain and more difficult to use safely. You can find a description of the principles from the following article.
Consider a situation in which you are concurrently developing on multiple platforms. Then consider adding a new platform or changing the platform definitions of an existing platform. What happens? Everything, and this does literally mean everything, recompiles. Isn't it quite absurd that adding a new platform, which has absolutely nothing to do with previously existing platforms, means that all code on all existing platforms needs to be recompiled?
Effectively, there is an imposed physical dependency between platforms that have nothing to do with each other. Essentially, the traditional solution employed by configuration headers does not conform to the Open-Closed Principle:
"A module should be open for extension but closed for modification."
Extending a traditional configuration header implies modifying existing code.
Furthermore, consider the complexity and fragility of the platform detection code. What if a simple change breaks the detection on some minor platform? What if someone accidentally or on purpose (as a workaround for some other problem) defines some platform dependent macros that are used by the detection code? A traditional configuration header is one of the most volatile headers of the entire library, and more stable elements of Boost would depend on it. This violates the Stable Dependencies Principle:
"Depend in the direction of stability."
After even a minor change to a traditional configuration header on one minor platform, almost everything on every platform should be tested if we follow sound software engineering practice.
Another important issue is that it is not always possible to submit changes
to <boost/config.hpp>
.
Some boost users are currently working on platforms using tools and libraries
that are under strict Non-Disclosure Agreements. In this situation it is
impossible to submit changes to a traditional monolithic configuration header,
instead some method by which the user can insert their own configuration
code must be provided.
The approach taken by boost's configuration headers is to separate configuration into three orthogonal parts: the compiler, the standard library and the platform. Each compiler/standard library/platform gets its own mini-configuration header, so that changes to one compiler's configuration (for example) does not affect other compilers. In addition there are measures that can be taken both to omit the compiler/standard library/platform detection code (so that adding support to a new platform does not break dependencies), or to freeze the configuration completely; providing almost complete protection against dependency changes.