[libcxx] Capture configuration information when installing the libc++ headers

Summary:
Hi all,

This patch is a successor to D11963. However it has changed dramatically and I felt it would be best to start a new review thread.

Please read the design documentation added in this patch for a description of how it works.

Reviewers: mclow.lists, danalbert, jroelofs, EricWF

Subscribers: vkalintiris, rnk, ed, espositofulvio, asl, eugenis, cfe-commits

Differential Revision: http://reviews.llvm.org/D13407

llvm-svn: 250235
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: f9f796e79b95a70346a945a589e833b71123e983
diff --git a/docs/DesignDocs/CapturingConfigInfo.rst b/docs/DesignDocs/CapturingConfigInfo.rst
new file mode 100644
index 0000000..0f16ca1
--- /dev/null
+++ b/docs/DesignDocs/CapturingConfigInfo.rst
@@ -0,0 +1,88 @@
+=======================================================
+Capturing configuration information during installation
+=======================================================
+
+.. contents::
+   :local:
+
+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.
+
+
+Design Goals
+============
+
+* The solution should not INSTALL any additional headers. We don't want an extra
+  #include slowing everybody down.
+
+* The solution should not unduly affect libc++ developers. The problem is limited
+  to installed versions of libc++ and the solution should be as well.
+
+* 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 dependant 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.
+
+
+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.
+
+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 prependend 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:
+
+.. code-block:: cpp
+
+  //===----------------------------------------------------------------------===//
+  //
+  //                     The LLVM Compiler Infrastructure
+  //
+  // This file is dual licensed under the MIT and the University of Illinois Open
+  // Source Licenses. See LICENSE.TXT for details.
+  //
+  //===----------------------------------------------------------------------===//
+
+  #ifndef _LIBCPP_CONFIG_SITE
+  #define _LIBCPP_CONFIG_SITE
+
+  /* #undef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE */
+  /* #undef _LIBCPP_HAS_NO_STDIN */
+  /* #undef _LIBCPP_HAS_NO_STDOUT */
+  #define _LIBCPP_HAS_NO_THREADS
+  /* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */
+  /* #undef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS */
+
+  #endif
+  // -*- C++ -*-
+  //===--------------------------- __config ---------------------------------===//
+  //
+  //                     The LLVM Compiler Infrastructure
+  //
+  // This file is dual licensed under the MIT and the University of Illinois Open
+  // Source Licenses. See LICENSE.TXT for details.
+  //
+  //===----------------------------------------------------------------------===//
+
+  #ifndef _LIBCPP_CONFIG
+  #define _LIBCPP_CONFIG
diff --git a/docs/index.rst b/docs/index.rst
index acd9229..f34979f 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -124,6 +124,12 @@
 Design Documents
 ----------------
 
+.. toctree::
+   :maxdepth: 1
+
+   DesignDocs/CapturingConfigInfo
+
+
 * `<atomic> design <http://libcxx.llvm.org/atomic_design.html>`_
 * `<type_traits> design <http://libcxx.llvm.org/type_traits_design.html>`_
 * `Status of debug mode <http://libcxx.llvm.org/debug_mode.html>`_