mirror of
				https://github.com/boostorg/config.git
				synced 2025-11-04 01:31:37 +01:00 
			
		
		
		
	
		
			
	
	
		
			81 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			81 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								[/
							 | 
						||
| 
								 | 
							
								    Boost.Config
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Copyright (c) 2001 Beman Dawes
							 | 
						||
| 
								 | 
							
								    Copyright (c) 2001 Vesa Karvonen
							 | 
						||
| 
								 | 
							
								    Copyright (c) 2001 John Maddock
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Distributed under the Boost Software License, Version 1.0.
							 | 
						||
| 
								 | 
							
								    (See accompanying file LICENSE_1_0.txt or copy at
							 | 
						||
| 
								 | 
							
								    http://www.boost.org/LICENSE_1_0.txt)
							 | 
						||
| 
								 | 
							
								]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[section Rationale]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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 __PRINCIPLES_AND_PATTERNS_ARTICLE__.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[section The problem]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[endsect]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[section The solution]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[endsect]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[endsect]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 |