blob: 402f4c7197c2fba09ee64ff81c49703b0865ad65 [file] [log] [blame]
Louis Dionneb1269812022-03-23 13:40:15 -04001==================================================
2Capturing configuration information in the headers
3==================================================
Eric Fiselier5cf9a822015-10-13 22:12:02 +00004
5.. contents::
6 :local:
7
8The Problem
9===========
10
Louis Dionneb1269812022-03-23 13:40:15 -040011libc++ supports building the library with a number of different configuration options.
12In order to support persistent configurations and reduce arbitrary preprocessor logic
13in the headers, libc++ has a mechanism to capture configuration options in the
14installed headers so they can be used in the rest of the code.
Eric Fiselier5cf9a822015-10-13 22:12:02 +000015
16
17Design Goals
18============
19
Louis Dionneb1269812022-03-23 13:40:15 -040020* The solution should be simple, consistent and robust to avoid subtle bugs.
Eric Fiselier5cf9a822015-10-13 22:12:02 +000021
Louis Dionneb1269812022-03-23 13:40:15 -040022* Developers should test the code the same way it will be deployed -- in other words,
23 the headers used to run tests should be the same that we install in order
24 to avoid bugs creeping up.
Eric Fiselier5cf9a822015-10-13 22:12:02 +000025
Louis Dionneb1269812022-03-23 13:40:15 -040026* It should allow different targets or flavors of the library to use a different
27 configuration without having to duplicate all the libc++ headers.
Eric Fiselier5cf9a822015-10-13 22:12:02 +000028
29
30The Solution
31============
32
Louis Dionneb1269812022-03-23 13:40:15 -040033When you first configure libc++ using CMake, a ``__config_site`` file is generated
34to capture the various configuration options you selected. The ``__config`` header
35used by all other headers includes this ``__config_site`` header first in order to
36get the correct configuration.
Eric Fiselier5cf9a822015-10-13 22:12:02 +000037
Louis Dionneb1269812022-03-23 13:40:15 -040038The ``__config_site`` header is hence the only place where persistent configuration
39is stored in the library. That header essentially reflects how the vendor configured
40the library. As we evolve the library, we can lift configuration options into that
41header in order to reduce arbitrary hardcoded choices elsewhere in the code. For
42example, instead of assuming that a specific platform doesn't provide some functionality,
43we can create a generic macro to guard it and vendors can define the macro when
44configuring the library on that platform. This makes the "carve off" reusable in
45other circumstances instead of tying it tightly to a single platform.
Eric Fiselier5cf9a822015-10-13 22:12:02 +000046
Louis Dionneb1269812022-03-23 13:40:15 -040047Furthermore, the Clang driver now looks for headers in a target-specific directory
48for libc++. By installing the ``__config_site`` header (and only that header) to
49this target-specific directory, it is possible to share the libc++ headers for
50multiple targets, and only duplicate the persistent information located in the
51``__config_site`` header. For example:
Eric Fiselier5cf9a822015-10-13 22:12:02 +000052
Louis Dionneb1269812022-03-23 13:40:15 -040053.. code-block:: bash
Eric Fiselier5cf9a822015-10-13 22:12:02 +000054
Louis Dionneb1269812022-03-23 13:40:15 -040055 include/c++/v1/
56 vector
57 map
58 etc...
Eric Fiselier5cf9a822015-10-13 22:12:02 +000059
Louis Dionneb1269812022-03-23 13:40:15 -040060 include/<targetA>/c++/v1/
61 __config_site
Eric Fiselier5cf9a822015-10-13 22:12:02 +000062
Louis Dionneb1269812022-03-23 13:40:15 -040063 include/<targetB>/c++/v1/
64 __config_site
Eric Fiselier5cf9a822015-10-13 22:12:02 +000065
Louis Dionneb1269812022-03-23 13:40:15 -040066When compiling for ``targetA``, Clang will use the ``__config_site`` inside
67``include/<targetA>/c++/v1/``, and the corresponding ``__config_site`` for
68``targetB``.