llvm-project/libcxx/docs/DesignDocs/HeaderRemovalPolicy.rst
Mark de Wever ddb6c2b301 [libc++] Rewrites graph_header_deps.py.
The new version is a lot simpler and has less option which were not
used. This uses the CSV files as generated by D133127 as input data.

The current Python script has more features but uses a simple "grep"
making the output less accurate:
- Conditionally included header are always included. This is an issue
  since part of our includes are unneeded transitive includes. Based on
  the language version they may be omitted. The script however always
  includes them.
- Includes in comments are processed as-if they are includes. This is an
  issue when comments explain how certain data is generated; of course
  there are digraphs which the script omits.

This implementation uses Clang's --trace-includes to generate the includes
per header. This means the input of the generation script always has the
real list of includes.

Libc++ is moving from large monolithic Standard headers to more fine
grained headers. For example, algorithm includes every header in
`__algorithm`. Adding all these detail headers in the graph makes the
output unusable. Instead it only shows the Standard headers. The
transitive includes of the detail headers are parsed and "attributed" to
the Standard header including them. This gives an accurate include graph
without the unneeded clutter. Note that this graph is still big.

This changes fixes the cyclic dependency issue with the previous version
of the tool so the markers and its documentation is removed.

Since the input has no cycles the CI test is removed.

Reviewed By: #libc, ldionne

Differential Revision: https://reviews.llvm.org/D134188
2022-09-25 15:06:21 +02:00

62 lines
2.9 KiB
ReStructuredText

=====================
Header Removal Policy
=====================
Policy
------
Libc++ is in the process of splitting larger headers into smaller modular
headers. This makes it possible to remove these large headers from other
headers. For example, instead of including ``<algorithm>`` entirely it is
possible to only include the headers for the algorithms used. When the
Standard indirectly adds additional header includes, using the smaller headers
aids reducing the growth of top-level headers. For example ``<atomic>`` uses
``std::chrono::nanoseconds`` and included ``<chrono>``. In C++20 ``<chrono>``
requires ``<format>`` which adds several other headers (like ``<string>``,
``<optional>``, ``<tuple>``) which are not needed in ``<atomic>``.
The benefit of using minimal headers is that the size of libc++'s top-level
headers becomes smaller. This improves the compilation time when users include
a top-level header. It also avoids header inclusion cycles and makes it easier
to port headers to platforms with reduced functionality.
A disadvantage is that users unknowingly depend on these transitive includes.
Thus removing an include might break their build after upgrading a newer
version of libc++. For example, ``<algorithm>`` is often forgotten but using
algorithms will still work through those transitive includes. This problem is
solved by modules, however in practice most people do not use modules (yet).
To ease the removal of transitive includes in libc++, libc++ will remove
unnecessary transitive includes in newly supported C++ versions. This means
that users will have to fix their missing includes in order to upgrade to a
newer version of the Standard. Libc++ also reserves the right to remove
transitive includes at any other time, however new language versions will be
used as a convenient way to perform bulk removals of transitive includes.
For libc++ developers, this means that any transitive include removal must be
guarded by something of the form:
.. code-block:: cpp
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <algorithm>
# include <iterator>
# include <utility>
#endif
When users define ``_LIBCPP_REMOVE_TRANSITIVE_INCLUDES``, libc++ will not
include transitive headers, regardless of the language version. This can be
useful for users to aid the transition to a newer language version, or by users
who simply want to make sure they include what they use in their code.
Rationale
---------
Removing headers is not only an issue for software developers, but also for
vendors. When a vendor updates libc++ several of their upstream packages might
fail to compile, forcing them to fix these packages or file a bug with their
upstream packages. Usually upgrading software to a new language standard is
done explicitly by software developers. This means they most likely will
discover and fix the missing includes, lessening the burden for the vendors.