Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions libcxx/docs/DesignDocs/Availability.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

====================
Availability markups
====================

Libc++ is shipped by various vendors. In particular, it is used as a system library on macOS, iOS and other Apple
platforms. In order for users to be able to compile a binary that is intended to be deployed to an older version of a
platform, Clang provides `availability attributes <https://clang.llvm.org/docs/AttributeReference.html#availability>`_.
These attributes can be placed on declarations and are used to describe the life cycle of a symbol in the library.

The main goal is to ensure a compile-time error if a symbol that hasn't been introduced in a previously released library
is used in a program that targets that previously released library. Normally, this would be a load-time error when one
tries to launch the program against the older library.

For example, the filesystem library was introduced in the dylib in LLVM 9. On Apple platforms, this corresponds to
macOS 10.15. If a user compiles on a macOS 10.15 host but targets macOS 10.13 with their program, the compiler would
normally not complain (because the required declarations are in the headers), but the dynamic loader would fail to find
the symbols when actually trying to launch the program on macOS 10.13. To turn this into a compile-time issue instead,
declarations are annotated with when they were introduced, and the compiler can produce a diagnostic if the program
references something that isn't available on the deployment target.


This mechanism is general in nature, and any vendor can add their markup to the library (see below). Whenever a new
feature is added that requires support in the shared library, two macros are added below to allow marking the feature as
unavailable:

1. A macro named ``_LIBCPP_AVAILABILITY_HAS_<feature>`` which must be defined to ``_LIBCPP_INTRODUCED_IN_<version>`` for
the appropriate LLVM version.

2. A macro named ``_LIBCPP_AVAILABILITY_<feature>``, which must be defined to ``_LIBCPP_INTRODUCED_IN_<version>_MARKUP``
for the appropriate LLVM version.

When vendors decide to ship the feature as part of their shared library, they can update the
``_LIBCPP_INTRODUCED_IN_<version>`` macro (and the markup counterpart) based on the platform version they shipped that
version of LLVM in. The library will then use this markup to provide an optimal user experience on these platforms.

Furthermore, many features in the standard library have corresponding feature-test macros. The
``_LIBCPP_AVAILABILITY_HAS_<feature>`` macros are checked by the corresponding feature-test macros generated by
``generate_feature_test_macro_components.py`` to ensure that the library doesn't announce a feature as being implemented
if it is unavailable on the deployment target.

Note that this mechanism is disabled by default in the "upstream" libc++. Availability annotations are only meaningful
when shipping libc++ inside a platform (i.e. as a system library), and so vendors that want them should turn those
annotations on at CMake configuration time.
1 change: 1 addition & 0 deletions libcxx/docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ Design Documents

DesignDocs/ABIVersioning
DesignDocs/AtomicDesign
DesignDocs/Availability
DesignDocs/CapturingConfigInfo
DesignDocs/ExperimentalFeatures
DesignDocs/ExtendedCXX03Support
Expand Down
50 changes: 1 addition & 49 deletions libcxx/include/__configuration/availability.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,55 +17,7 @@
# pragma GCC system_header
#endif

// Libc++ is shipped by various vendors. In particular, it is used as a system
// library on macOS, iOS and other Apple platforms. In order for users to be
// able to compile a binary that is intended to be deployed to an older version
// of a platform, Clang provides availability attributes [1]. These attributes
// can be placed on declarations and are used to describe the life cycle of a
// symbol in the library.
//
// The main goal is to ensure a compile-time error if a symbol that hasn't been
// introduced in a previously released library is used in a program that targets
// that previously released library. Normally, this would be a load-time error
// when one tries to launch the program against the older library.
//
// For example, the filesystem library was introduced in the dylib in LLVM 9.
// On Apple platforms, this corresponds to macOS 10.15. If a user compiles on
// a macOS 10.15 host but targets macOS 10.13 with their program, the compiler
// would normally not complain (because the required declarations are in the
// headers), but the dynamic loader would fail to find the symbols when actually
// trying to launch the program on macOS 10.13. To turn this into a compile-time
// issue instead, declarations are annotated with when they were introduced, and
// the compiler can produce a diagnostic if the program references something that
// isn't available on the deployment target.
//
// This mechanism is general in nature, and any vendor can add their markup to
// the library (see below). Whenever a new feature is added that requires support
// in the shared library, two macros are added below to allow marking the feature
// as unavailable:
// 1. A macro named `_LIBCPP_AVAILABILITY_HAS_<feature>` which must be defined
// to `_LIBCPP_INTRODUCED_IN_<version>` for the appropriate LLVM version.
// 2. A macro named `_LIBCPP_AVAILABILITY_<feature>`, which must be defined to
// `_LIBCPP_INTRODUCED_IN_<version>_MARKUP` for the appropriate LLVM version.
//
// When vendors decide to ship the feature as part of their shared library, they
// can update the `_LIBCPP_INTRODUCED_IN_<version>` macro (and the markup counterpart)
// based on the platform version they shipped that version of LLVM in. The library
// will then use this markup to provide an optimal user experience on these platforms.
//
// Furthermore, many features in the standard library have corresponding
// feature-test macros. The `_LIBCPP_AVAILABILITY_HAS_<feature>` macros
// are checked by the corresponding feature-test macros generated by
// generate_feature_test_macro_components.py to ensure that the library
// doesn't announce a feature as being implemented if it is unavailable on
// the deployment target.
//
// Note that this mechanism is disabled by default in the "upstream" libc++.
// Availability annotations are only meaningful when shipping libc++ inside
// a platform (i.e. as a system library), and so vendors that want them should
// turn those annotations on at CMake configuration time.
//
// [1]: https://clang.llvm.org/docs/AttributeReference.html#availability
// Documentation for this utility can be found at https://libcxx.llvm.org/DesignDocs/Availability.html

// Availability markup is disabled when building the library, or when a non-Clang
// compiler is used because only Clang supports the necessary attributes.
Expand Down
Loading