diff --git a/libcxx/docs/DesignDocs/CapturingConfigInfo.rst b/libcxx/docs/DesignDocs/CapturingConfigInfo.rst index 3ab078e07d77..402f4c7197c2 100644 --- a/libcxx/docs/DesignDocs/CapturingConfigInfo.rst +++ b/libcxx/docs/DesignDocs/CapturingConfigInfo.rst @@ -1,6 +1,6 @@ -======================================================= -Capturing configuration information during installation -======================================================= +================================================== +Capturing configuration information in the headers +================================================== .. contents:: :local: @@ -8,75 +8,61 @@ Capturing configuration information during installation The Problem =========== -Currently the libc++ supports building the library with a number of different -configuration options. Unfortunately all of that configuration information is -lost when libc++ is installed. In order to support "persistent" -configurations libc++ needs a mechanism to capture the configuration options -in the INSTALLED headers. +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 not INSTALL any additional headers. We don't want an extra - #include slowing everybody down. +* The solution should be simple, consistent and robust to avoid subtle bugs. -* The solution should not unduly affect libc++ developers. The problem is limited - to installed versions of libc++ and the solution should be as well. +* 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. -* The solution should not modify any existing headers EXCEPT during installation. - It makes developers lives harder if they have to regenerate the libc++ headers - every time they are modified. - -* The solution should not make any of the libc++ headers dependent on - files generated by the build system. The headers should be able to compile - out of the box without any modification. - -* The solution should not have ANY effect on users who don't need special - configuration options. The vast majority of users will never need this so it - shouldn't cost them. +* 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 we check to see if we need to -capture any options. If we haven't been given any "persistent" options then -we do NOTHING. +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. -Otherwise we create a custom installation rule that modifies the installed __config -header. The rule first generates a dummy "__config_site" header containing the required -#defines. The contents of the dummy header are then prepended to the installed -__config header. By manually prepending the files we avoid the cost of an -extra #include and we allow the __config header to be ignorant of the extra -configuration all together. An example "__config" header generated when --DLIBCXX_ENABLE_THREADS=OFF is given to CMake would look something like: +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. -.. code-block:: cpp +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: - //===----------------------------------------------------------------------===// - // - // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. - // See https://llvm.org/LICENSE.txt for license information. - // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - // - //===----------------------------------------------------------------------===// +.. code-block:: bash - #ifndef _LIBCPP_CONFIG_SITE - #define _LIBCPP_CONFIG_SITE + include/c++/v1/ + vector + map + etc... - #define _LIBCPP_HAS_NO_THREADS - /* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */ + include//c++/v1/ + __config_site - #endif - // -*- C++ -*- - //===----------------------------------------------------------------------===// - // - // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. - // See https://llvm.org/LICENSE.txt for license information. - // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - // - //===----------------------------------------------------------------------===// + include//c++/v1/ + __config_site - #ifndef _LIBCPP_CONFIG - #define _LIBCPP_CONFIG +When compiling for ``targetA``, Clang will use the ``__config_site`` inside +``include//c++/v1/``, and the corresponding ``__config_site`` for +``targetB``.