diff --git a/libcxx/docs/DesignDocs/Availability.rst b/libcxx/docs/DesignDocs/Availability.rst new file mode 100644 index 0000000000000..461d23106ff7a --- /dev/null +++ b/libcxx/docs/DesignDocs/Availability.rst @@ -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 `_. +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_`` which must be defined to ``_LIBCPP_INTRODUCED_IN_`` for + the appropriate LLVM version. + +2. A macro named ``_LIBCPP_AVAILABILITY_``, which must be defined to ``_LIBCPP_INTRODUCED_IN__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_`` 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_`` 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. diff --git a/libcxx/docs/index.rst b/libcxx/docs/index.rst index d006b52f24cec..cc6f5d0cb310c 100644 --- a/libcxx/docs/index.rst +++ b/libcxx/docs/index.rst @@ -212,6 +212,7 @@ Design Documents DesignDocs/ABIVersioning DesignDocs/AtomicDesign + DesignDocs/Availability DesignDocs/CapturingConfigInfo DesignDocs/ExperimentalFeatures DesignDocs/ExtendedCXX03Support diff --git a/libcxx/include/__configuration/availability.h b/libcxx/include/__configuration/availability.h index 5433df872fa39..73a5a0ed2897d 100644 --- a/libcxx/include/__configuration/availability.h +++ b/libcxx/include/__configuration/availability.h @@ -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_` which must be defined -// to `_LIBCPP_INTRODUCED_IN_` for the appropriate LLVM version. -// 2. A macro named `_LIBCPP_AVAILABILITY_`, which must be defined to -// `_LIBCPP_INTRODUCED_IN__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_` 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_` 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.