|  | ================================================== | 
|  | Capturing configuration information in the headers | 
|  | ================================================== | 
|  |  | 
|  | .. contents:: | 
|  | :local: | 
|  |  | 
|  | The Problem | 
|  | =========== | 
|  |  | 
|  | libc++ supports building the library with a number of different configuration options. | 
|  | In order to support persistent configurations and reduce arbitrary preprocessor logic | 
|  | in the headers, libc++ has a mechanism to capture configuration options in the | 
|  | installed headers so they can be used in the rest of the code. | 
|  |  | 
|  |  | 
|  | Design Goals | 
|  | ============ | 
|  |  | 
|  | * The solution should be simple, consistent and robust to avoid subtle bugs. | 
|  |  | 
|  | * Developers should test the code the same way it will be deployed -- in other words, | 
|  | the headers used to run tests should be the same that we install in order | 
|  | to avoid bugs creeping up. | 
|  |  | 
|  | * It should allow different targets or flavors of the library to use a different | 
|  | configuration without having to duplicate all the libc++ headers. | 
|  |  | 
|  |  | 
|  | The Solution | 
|  | ============ | 
|  |  | 
|  | When you first configure libc++ using CMake, a ``__config_site`` file is generated | 
|  | to capture the various configuration options you selected. The ``__config`` header | 
|  | used by all other headers includes this ``__config_site`` header first in order to | 
|  | get the correct configuration. | 
|  |  | 
|  | The ``__config_site`` header is hence the only place where persistent configuration | 
|  | is stored in the library. That header essentially reflects how the vendor configured | 
|  | the library. As we evolve the library, we can lift configuration options into that | 
|  | header in order to reduce arbitrary hardcoded choices elsewhere in the code. For | 
|  | example, instead of assuming that a specific platform doesn't provide some functionality, | 
|  | we can create a generic macro to guard it and vendors can define the macro when | 
|  | configuring the library on that platform. This makes the "carve off" reusable in | 
|  | other circumstances instead of tying it tightly to a single platform. | 
|  |  | 
|  | Furthermore, the Clang driver now looks for headers in a target-specific directory | 
|  | for libc++. By installing the ``__config_site`` header (and only that header) to | 
|  | this target-specific directory, it is possible to share the libc++ headers for | 
|  | multiple targets, and only duplicate the persistent information located in the | 
|  | ``__config_site`` header. For example: | 
|  |  | 
|  | .. code-block:: bash | 
|  |  | 
|  | include/c++/v1/ | 
|  | vector | 
|  | map | 
|  | etc... | 
|  |  | 
|  | include/<targetA>/c++/v1/ | 
|  | __config_site | 
|  |  | 
|  | include/<targetB>/c++/v1/ | 
|  | __config_site | 
|  |  | 
|  | When compiling for ``targetA``, Clang will use the ``__config_site`` inside | 
|  | ``include/<targetA>/c++/v1/``, and the corresponding ``__config_site`` for | 
|  | ``targetB``. |