diff --git a/en/xclang/design/roadmap.md b/en/xclang/design/roadmap.md index 540fae9ae..df29ad944 100644 --- a/en/xclang/design/roadmap.md +++ b/en/xclang/design/roadmap.md @@ -171,8 +171,10 @@ its C compiler and linker. Every toolchain archive carries it, as | item | status | |---|---| -| libc++, libc++abi and libunwind built from source on demand | Planned | -| MemorySanitizer, through libc++ built on demand | Planned | +| libc++, libc++abi and libunwind built from source on demand | Unreleased | +| MemorySanitizer, through libc++ built on demand | Unreleased | +| Runtimes from source for the MSVC targets | Planned | +| LTO of the runtimes from source with the program, in Bazel | Considered | | Sanitizers for MinGW targets | Considered | | ASan, TSan, LSan and libFuzzer for musl targets, with a dynamically linked musl (Alpine's way) | Considered | | `@xclang//bazel:llvm-gsymutil`, the toolchain's llvm-gsymutil for `bazel run` | Supported | @@ -187,16 +189,29 @@ its C compiler and linker. Every toolchain archive carries it, as **libc++ built on demand** means libc++, libc++abi and libunwind built from source inside a CMake or Bazel build, from LLVM's runtime sources of the -release, with its [patches](../reference/patches.md). It covers what the -prebuilt runtimes cannot be: - -- **MemorySanitizer**, which needs every library instrumented, libc++ too. - ThreadSanitizer also reports better through an instrumented libc++. +release, with its [patches](../reference/patches.md), which every toolchain +carries in `libc++/src` +([runtimes from source](../features/runtimes-from-source.md)). On `main`, +the CMake package's toolchain file (`XCLANG_RUNTIMES=source`) and the Bazel +module (`--@xclang//runtimes:source`) build them for every target but the +MSVC ones. They cover what the prebuilt runtimes cannot be: + +- **MemorySanitizer**, which needs every library instrumented, libc++ too, + and compiler-rt's runtime of it, built with them. ThreadSanitizer and + AddressSanitizer also report through an instrumented libc++. - **Hardening and ABI options**: a hardening mode checked inside the library, libc++'s ABI version 2, bounded iterators, an ABI namespace of one's own, and builds without exceptions or RTTI. -- **LTO and PGO** of libc++ together with the program. -- **Targets without prebuilt runtimes**: tier 3 ones and Apple's devices. +- **LTO** of libc++ together with the program, in CMake builds. Bazel runs + ThinLTO's backends only for the objects of the libraries it knows, which + the runtimes, linked by the toolchain, are not: making them such + libraries is considered. +- **Targets without prebuilt runtimes**: tier 3 ones and Apple's devices, + once they are targets. + +The MSVC targets' libc++ builds on Microsoft's C++ ABI library with +clang-cl, against the fetched SDK; building it from source there is +planned. The prebuilt runtimes stay the default. diff --git a/en/xclang/dev/testing.md b/en/xclang/dev/testing.md index 33ed1462b..33ce9fef8 100644 --- a/en/xclang/dev/testing.md +++ b/en/xclang/dev/testing.md @@ -44,8 +44,8 @@ rest are called by them, by release.yml, or started by hand. |---|---|---|---|---|---| | docs.yml | every push and pull request, by itself | | | | `tests/docs/docs.ts` and the types (`npm run check`); on `main`, then publishing to docs.clice.io | | test-archives.yml | `tests/toolchain`, `tests/libclang`, `toolchain/config` | stage `test` | | | `tests/toolchain/smoke.ts` and `tests/libclang/libclang.ts` on a machine of each host; the programs the smoke test builds for other targets run on those (on-target.yml); with `repack-of`, `tests/release/repack.ts`: each host's archives against those of the release repacked (or of an earlier run of the same revision, which a full rebuild must give again), file by file, only the packaging's files differ | -| test-cmake.yml | `packages/cmake`, `tests/cmake`, `tests/libclang` | stage `cmake` | the tag fetched from GitHub | | `tests/cmake/cmake.ts`: the package by `PATH`, through the toolchain file, and from FetchContent | -| test-bazel.yml | `packages/bazel`, `tests/bazel` | stage `bazel`: `tests/bazel` only | ✓ | ✓ | `tests/bazel` with the module, `tests/bazel/bazel.ts`, and cross builds run on the target (`tests/bazel/cross.ts`) | +| test-cmake.yml | `packages/cmake`, `tests/cmake`, `tests/libclang`, `toolchain/runtimes-src.ts`, `toolchain/cmake/caches` | stage `cmake` | the tag fetched from GitHub | | `tests/cmake/cmake.ts`: the package by `PATH`, through the toolchain file, from FetchContent, and with the runtimes from source; their programs for other targets run there (on-target.yml) | +| test-bazel.yml | `packages/bazel`, `tests/bazel`, `toolchain/runtimes-src.ts` | stage `bazel`: `tests/bazel` and the runtimes from source | ✓ | ✓ | `tests/bazel` with the module, `tests/bazel/bazel.ts`, the runtimes from source (`tests/bazel/runtimes.ts`), and cross builds run on the target (`tests/bazel/cross.ts`) | | test-sdk.yml | `tests/sdk`, `toolchain/config`, `packages/cmake` | stage `sdk`; needs `cli`, as the archives' `xclang` fetches the SDKs | | | the MSVC targets (`tests/sdk/msvc.ts`) and the macOS targets from Linux and Windows hosts (`tests/sdk/macos.ts`); their programs on Windows and Macs | | cli.yml | `xclang`, `tests/cli`, `tests/sdk` | the build, for stage `package`; stage `cli` | | ✓ | the `xclang` command: rustfmt, clippy, unit tests, `tests/cli/cli.ts`, `tests/cli/cargo.ts` | | examples.yml | `examples` | | once conda.clice.io has the release and `latest` names it | ✓ | the commands and `examples/` of the docs, as written; the programs for other targets on their runners | @@ -164,6 +164,19 @@ Ninja 1.11, and with the newest of both: downloads `SHA256SUMS` and the host toolchain. 4. `tests/libclang` with the ThinLTO cache. A second link takes every module's code from the cache, and the program is the same. +5. **The runtimes from source**, with a toolchain that has their sources + (the archives action adds this checkout's to a release before them): + `tests/cmake/runtimes` once per variant, through the toolchain file. + With no options they are the prebuilt runtimes again: the same + `__config_site` and module sources, and for Linux and MinGW the same + code. A hardening mode traps on a read past a vector's end; an ABI + namespace and ABI macros of its own, without exceptions and RTTI, name + the code of `import std` in the program; on Linux x64, MemorySanitizer + reports a use of uninitialized memory inside libc++ and nothing of what + libc++ itself writes, and libc++ of ThinLTO is bitcode. From Linux x64 + (to Linux arm64 and both MinGW targets) and arm64 macOS (to x86_64 + macOS), with the newest CMake, the hardening variant's programs run on a + machine of the target (on-target.yml). `tests/cmake` covers a C++ module of partitions, `xclang::std` with `std.compat`, `xclang_add_std` with `-fno-exceptions`, and @@ -216,6 +229,17 @@ and libclang; a Linux host runs the musl tests of its architecture `modules_embed_all_files`, an importer cannot open the source of the module it imports. +`tests/bazel/runtimes.ts`, after them, builds `tests/bazel/runtimes` with the +runtimes from source (`--@xclang//runtimes:source`), with a toolchain that +has their sources, once per variant: with no options, the prebuilt +`__config_site` again; a hardening mode that traps; an ABI namespace and +ABI macros without exceptions and RTTI, which the code of `import std` is +named with; on Linux x64, `--features=msan` reporting inside libc++ and not +on what it writes, and `--features=thin_lto`. From Linux x64 and arm64 +macOS, the hardening variant for other targets runs on their machines. +`packages/bazel/runtimes.ts check` (by hand) says whether +`runtimes_sources.bzl` is still what LLVM's CMake build compiles. + test-bazel.yml's cross jobs build `tests/bazel` on every host for every other target, and run its tests on a runner of that target. Its sdk jobs do the same for the targets of the vendor SDKs, the module accepting their diff --git a/en/xclang/features/runtimes-from-source.md b/en/xclang/features/runtimes-from-source.md new file mode 100644 index 000000000..ebaf9c550 --- /dev/null +++ b/en/xclang/features/runtimes-from-source.md @@ -0,0 +1,152 @@ +# C++ Runtimes from Source + +xclang's prebuilt C++ runtimes are one build of libc++, libc++abi and +libunwind per target: no hardening mode, ABI version 1, exceptions and +RTTI, no instrumentation but the ASan libc++ +([sanitizers](sanitizers.md)). A CMake or Bazel build can instead compile +them from the sources every toolchain carries, with options of its own, and +link its programs against those. This is for what the prebuilt runtimes +cannot be: + +- **MemorySanitizer**, which needs every library instrumented, libc++ too, + and compiler-rt's runtime of it, which the toolchain does not carry. + ThreadSanitizer and AddressSanitizer report through an instrumented + libc++ too. +- **libc++'s hardening modes**, checked inside the library as well as in + its headers. +- **ABI options**: libc++'s ABI version 2, bounded iterators, an inline + namespace of one's own. +- **No exceptions, no RTTI** in libc++ and libc++abi. +- **LTO of libc++ with the program** (CMake). + +The prebuilt runtimes stay the default. Runtimes from source are in no +release yet ([Unreleased](../design/roadmap.md#libc-on-demand)); the +toolchains of the release after 23.1.2.10 carry the sources. + +## Usage + +### CMake + +The option is the toolchain file's, `XCLANG_RUNTIMES=source`, with +libc++'s options next to it: + + +```sh +cmake -G Ninja -B build --toolchain "$XCLANG/lib/cmake/xclang/toolchain.cmake" \ + -DXCLANG_RUNTIMES=source -DXCLANG_LIBCXX_HARDENING=fast +cmake --build build +``` + +The first configure builds the variant, about half a minute on four cores, +into `build/xclang-runtimes/-`; later configures use it, and +other options make another variant beside it. Every compile and link of the +build is against it, CMake's own checks too, and `xclang::std` is built +from its modules. A MemorySanitizer build, which builds compiler-rt's +runtime of it first: + + +```sh +cmake -G Ninja -B build-msan --toolchain "$XCLANG/lib/cmake/xclang/toolchain.cmake" \ + -DXCLANG_RUNTIMES=source -DXCLANG_SANITIZER=memory -DCMAKE_BUILD_TYPE=RelWithDebInfo +``` + +`XCLANG_SANITIZER` gives the whole build its `-fsanitize=` and runtimes +that suit it, so the project's flags need no `-fsanitize=` of their own. +With the prebuilt runtimes it works too, for the sanitizers they have: +`address` then links the prebuilt ASan libc++. + +For another target, add `-DXCLANG_TARGET=`: the variant is built for +it, by the same toolchain file. + +### Bazel + +The flags of the whole build are in `@xclang//runtimes`, and the +sanitizers are the features they always were: + + +```sh +bazel build --@xclang//runtimes:source --@xclang//runtimes:hardening=fast //... +bazel test --@xclang//runtimes:source --features=msan //... +``` + +The runtimes are libraries of the toolchain's repository, compiled for the +target platform with the build's features (a sanitizer's instrumentation) +and `--copt`, and cached as any other action. A `.bazelrc` names the +variants a project uses: + +```text +build:msan --@xclang//runtimes:source --features=msan +build:hardened --@xclang//runtimes:source --@xclang//runtimes:hardening=extensive +``` + +## Options + +| | CMake (toolchain file) | Bazel | +|---|---|---| +| runtimes from source | `XCLANG_RUNTIMES=source` | `--@xclang//runtimes:source` | +| libc++'s hardening mode: `none`, `fast`, `extensive`, `debug` | `XCLANG_LIBCXX_HARDENING` | `--@xclang//runtimes:hardening` | +| libc++'s ABI version, `1` or `2` | `XCLANG_LIBCXX_ABI_VERSION` | `--@xclang//runtimes:abi_version` | +| libc++'s inline namespace, `__` | `XCLANG_LIBCXX_ABI_NAMESPACE` | `--@xclang//runtimes:abi_namespace` | +| libc++'s ABI macros, `_LIBCPP_ABI_*` | `XCLANG_LIBCXX_ABI_DEFINES` (a list) | `--@xclang//runtimes:abi_defines` (comma-separated) | +| libc++ and libc++abi without exceptions | `XCLANG_RUNTIMES_EXCEPTIONS=OFF` | `--@xclang//runtimes:exceptions=false` | +| libc++ without RTTI (and without exceptions) | `XCLANG_RUNTIMES_RTTI=OFF` | `--@xclang//runtimes:rtti=false` | +| sanitizers: `address`, `memory`, `thread`, `undefined`, `leak` | `XCLANG_SANITIZER` | `--features=asan`, `msan`, `tsan`, `ubsan`, `lsan` | +| more compile options of libc++ and libc++abi | `XCLANG_RUNTIMES_FLAGS` | the build's `--copt` | +| LTO of libc++ with the program | `XCLANG_RUNTIMES_FLAGS=-flto=thin` | not available | +| more options of LLVM's CMake build | `XCLANG_RUNTIMES_CMAKE_ARGS` | | +| where the variants are built | `XCLANG_RUNTIMES_DIR` | Bazel's output base and caches | + +The program's own options are its own: a build without exceptions passes +`-fno-exceptions` (`CMAKE_CXX_FLAGS`, `--copt`) as well. The +[CMake API](../reference/cmake-api.md#runtimes-from-source) and the +[Bazel API](../reference/bazel-api.md#runtimes-from-source) list them again. + +## Behavior + +- **The same build as the prebuilt runtimes.** CMake builds LLVM's + `runtimes/` with the CMake cache and options of xclang's own build of + the runtimes, by the toolchain file and the config file of the target. + With no options, the result is the prebuilt runtimes: the same + `__config_site`, and the same code. Bazel compiles the same translation + units with the same flags, which `packages/bazel/runtimes.ts` takes from + LLVM's CMake build of every target. +- **What is built**: libc++ with libc++abi in it, libc++experimental, and + libunwind (none for macOS, which unwinds with the system's). With + MemorySanitizer, compiler-rt's runtime of it. +- **In place of the prebuilt ones.** The variant's `__config_site` comes + before libc++'s other headers, and its libraries are linked instead of + the prebuilt ones (`-nostdlib++`). `import std` follows the variant: + `xclang::std` and `@xclang//bazel:std` are built from it. +- **libunwind stays uninstrumented** with sanitizers, as in the prebuilt + ASan libc++: the sanitizers' runtimes unwind with it, and MemorySanitizer + would report the registers it reads. +- **MemorySanitizer is for the Linux targets** (glibc), x64 and arm64. Its + runtime is linked into executables as clang links the others, whole, with + its interface exported. +- **Every library of a program must use the same variant.** A library + built against the prebuilt runtimes, with another ABI namespace, ABI + version or set of ABI macros, does not link, or breaks at run time; under + MemorySanitizer, its code reports what it was not instrumented to see. +- **Bazel does not run ThinLTO on the runtimes**: `--features=thin_lto` + links programs of ThinLTO against runtimes of native code. Bazel's ThinLTO + backends compile the objects of the libraries it knows, and the toolchain + links the runtimes' by their paths. +- **CMake needs Python 3**, as LLVM's build of the runtimes does. Bazel + needs nothing more. + +## The Sources + +Every toolchain directory has the sources once, for every target, in +`libc++/src`, next to libc++'s headers: llvm-project's own layout +(`runtimes/`, `cmake/`, `llvm/cmake/`, `libcxx/`, `libcxxabi/`, +`libunwind/`, `compiler-rt/`, and the headers of LLVM's libc that libc++ +includes), without tests and documentation, with xclang's +[patches](../reference/patches.md) of libc++ applied. They are 35 MB +unpacked, 2.3 MB of each archive. + +## Not Yet Supported + +| | status | +|---|---| +| [Runtimes from source for the MSVC targets](../design/roadmap.md#runtimes-msvc) | Planned | +| [LTO of the runtimes with the program in Bazel](../design/roadmap.md#runtimes-bazel-lto) | Considered | diff --git a/en/xclang/features/sanitizers.md b/en/xclang/features/sanitizers.md index 36923b4af..d1d823dfd 100644 --- a/en/xclang/features/sanitizers.md +++ b/en/xclang/features/sanitizers.md @@ -281,9 +281,12 @@ clang++ --target=x86_64-unknown-linux-musl -fsanitize=undefined -O1 ubsan.cpp -o |---|---| | [Sanitizers for MinGW targets](../design/roadmap.md#mingw-sanitizers) | Considered | | [ASan, TSan, LSan and libFuzzer for musl targets](../design/roadmap.md#musl-sanitizers) | Considered | -| [MemorySanitizer](../design/roadmap.md#msan) | Planned | +| [MemorySanitizer](../design/roadmap.md#msan) | Unreleased | MemorySanitizer needs every library instrumented, libc++ too, and -ThreadSanitizer reports better through an instrumented libc++. Both need -libc++ built from source with the options of the program, which is -[planned](../design/roadmap.md#libc-on-demand). +compiler-rt's runtime of it, which the toolchain does not carry. On `main`, +the runtimes built from source give it both, for the Linux targets +([runtimes from source](runtimes-from-source.md)): `XCLANG_RUNTIMES=source` +with `XCLANG_SANITIZER=memory` in CMake, `--@xclang//runtimes:source` with +`--features=msan` in Bazel. ThreadSanitizer and AddressSanitizer report +through runtimes from source as well, instrumented like the program. diff --git a/en/xclang/guide/comparisons.md b/en/xclang/guide/comparisons.md index 43e563bc9..cd01f719c 100644 --- a/en/xclang/guide/comparisons.md +++ b/en/xclang/guide/comparisons.md @@ -180,7 +180,7 @@ libclang. | [Android](../design/roadmap.md#android), [WebAssembly](../design/roadmap.md#wasm), [the BSDs](../design/roadmap.md#freebsd), [bare metal](../design/roadmap.md#bare-metal) | Considered | the NDK, wasi-sdk, zig cc | | [iOS and Apple's other devices](../design/roadmap.md#ios) | In research | Xcode | | [Windows 7 and XP](../design/roadmap.md#windows-7) | In research | llvm-mingw's msvcrt variant | -| [Runtimes built from source with other options: MemorySanitizer, libc++ hardening, an ABI of one's own](../design/roadmap.md#libc-on-demand) | Planned | zig cc builds its runtimes on first use | +| [Runtimes built from source with other options: MemorySanitizer, libc++ hardening, an ABI of one's own](../design/roadmap.md#libc-on-demand) | Unreleased | zig cc builds its runtimes on first use | ## Known Limitations diff --git a/en/xclang/guide/why-xclang.md b/en/xclang/guide/why-xclang.md index e936538fb..3e4f7f3d8 100644 --- a/en/xclang/guide/why-xclang.md +++ b/en/xclang/guide/why-xclang.md @@ -123,7 +123,7 @@ FetchContent or the Bazel registry. | | status | |---|---| | [More Linux architectures, WebAssembly, Android, BSDs, bare metal](../design/roadmap.md#targets) | Considered | -| [MemorySanitizer, through libc++ built on demand](../design/roadmap.md#msan) | Planned | +| [MemorySanitizer, through libc++ built on demand](../design/roadmap.md#msan) | Unreleased | | [Sanitizers for MinGW targets](../design/roadmap.md#mingw-sanitizers) | Considered | | [Relative debug paths in CMake builds](../design/roadmap.md#cmake-relative-paths) | Planned | | [Immutable releases](../design/roadmap.md#immutable-releases) | Planned | diff --git a/en/xclang/integrations/bazel.md b/en/xclang/integrations/bazel.md index 25d793377..a1638980a 100644 --- a/en/xclang/integrations/bazel.md +++ b/en/xclang/integrations/bazel.md @@ -228,6 +228,13 @@ sanitizers. The MSVC targets have `ubsan`, and x64 also has `asan`. ASan's runtime there is a DLL, which a program finds beside itself or on `PATH` ([MSVC targets](../features/sanitizers.md#msvc-targets)). +With `--@xclang//runtimes:source`, libc++, libc++abi and libunwind are +built from the toolchain's sources, instrumented by the build's sanitizer +features, and `msan` works too, for the Linux targets +([runtimes from source](../features/runtimes-from-source.md#bazel)); the +same flag takes libc++'s hardening and ABI options. It is in no release +yet. + ## Debug in gdb, lldb and VS Code Every path in the debug information is relative to the execution root diff --git a/en/xclang/integrations/cmake.md b/en/xclang/integrations/cmake.md index b6a1d906d..7ec116f99 100644 --- a/en/xclang/integrations/cmake.md +++ b/en/xclang/integrations/cmake.md @@ -257,6 +257,16 @@ importer's ([matching options](../features/modules.md#behavior)). So: Before putting ccache in front of the compiler, read [build caches and modules](../features/modules.md#build-caches-and-modules). +## Build the C++ Runtimes from Source + +With the toolchain file, `-DXCLANG_RUNTIMES=source` builds libc++, +libc++abi and libunwind from the toolchain's sources at the first +configure, with options the prebuilt ones lack: MemorySanitizer +(`-DXCLANG_SANITIZER=memory`), libc++'s hardening modes, ABI options, no +exceptions. The whole build, `xclang::std` included, is then against +them. It is in no release yet +([runtimes from source](../features/runtimes-from-source.md#cmake)). + ## Ship Debug Symbols `xclang_debug_symbols()` makes the debug symbols of a program diff --git a/en/xclang/reference/bazel-api.md b/en/xclang/reference/bazel-api.md index 523d8c949..c8339fabd 100644 --- a/en/xclang/reference/bazel-api.md +++ b/en/xclang/reference/bazel-api.md @@ -58,7 +58,8 @@ Windows unless it names one of those. | feature | default | | |---|---|---| -| `asan`, `tsan`, `ubsan`, `lsan` | off | sanitizers, for the whole build (`--features=asan`); `asan` compiles and links with the ASan libc++. None for the MinGW targets; for the MSVC targets `ubsan`, and `asan` for x64 | +| `asan`, `tsan`, `ubsan`, `lsan` | off | sanitizers, for the whole build (`--features=asan`); `asan` compiles and links with the ASan libc++, or with the runtimes from source instrumented by it. None for the MinGW targets; for the MSVC targets `ubsan`, and `asan` for x64 | +| `msan` | off | MemorySanitizer, for the whole build, with the runtimes from source (`--@xclang//runtimes:source`), which then include its runtime; Linux targets (glibc). In no release yet | | `cpp_modules` | off | C++20 modules: `module_interfaces` of a `cc_library`/`cc_binary`, scanned by clang-scan-deps; needs `--experimental_cpp_modules` | | `gc_sections` | Linux targets: on in `opt`; Windows targets: off | lld's `--gc-sections`, lld-link's `/opt:ref` for the MSVC targets ([why not for Windows](../design/windows.md#gc-sections-and-static-initializers)) | | `thinlto_cache` | on | the linker's ThinLTO cache, with flags only when `XCLANG_THINLTO_CACHE` names a directory | @@ -76,6 +77,29 @@ A feature is turned on for a build with `--features=`, off with `--features=-`, and for one target with `features = [""]` or `["-"]`. +## Runtimes from Source + +In no release yet ([Unreleased](../design/roadmap.md#libc-on-demand)). +Flags of the whole build, in `@xclang//runtimes` +([runtimes from source](../features/runtimes-from-source.md)): + +| flag | default | | +|---|---|---| +| `--@xclang//runtimes:source` | `false` | libc++ (with libc++abi), libc++experimental and libunwind built from the toolchain's `libc++/src` for the target platform, with the build's features and `--copt`, and every compile and link against them in place of the prebuilt ones. Not for the MSVC targets | +| `--@xclang//runtimes:hardening` | `none` | libc++'s hardening mode: `none`, `fast`, `extensive`, `debug` | +| `--@xclang//runtimes:abi_version` | `1` | libc++'s ABI version, `1` or `2` | +| `--@xclang//runtimes:abi_namespace` | `__` | libc++'s inline namespace, `__` | +| `--@xclang//runtimes:abi_defines` | none | libc++'s ABI macros, `_LIBCPP_ABI_*`, comma-separated | +| `--@xclang//runtimes:exceptions` | `true` | `false`: libc++ and libc++abi without exceptions | +| `--@xclang//runtimes:rtti` | `true` | `false`: libc++ without RTTI; needs `exceptions=false` | + +The runtimes are libraries of the host toolchain's repository, compiled as +LLVM's CMake build compiles them (`bazel/runtimes_sources.bzl`) in a +configuration of their own, the build's with `@xclang//runtimes:building` +set, whose toolchain is the same without them. The build's sanitizer +features instrument libc++ and libc++abi, not libunwind or +MemorySanitizer's runtime. No runtime is compiled with ThinLTO. + ## Targets and Rules | label | | diff --git a/en/xclang/reference/cmake-api.md b/en/xclang/reference/cmake-api.md index 7af2eefbc..01c9ed68b 100644 --- a/en/xclang/reference/cmake-api.md +++ b/en/xclang/reference/cmake-api.md @@ -15,6 +15,8 @@ Ninja Multi-Config generator, with Ninja 1.11 or later. | `xclang-config.cmake` | `find_package(xclang)`: `xclang::std`, `xclang_add_std()`, `xclang_debug_symbols()`, `XCLANG_ROOT`, the ThinLTO cache | | `xclang-config-version.cmake` | the release, for `find_package(xclang 23.1)` (toolchain archives only) | | `toolchain.cmake` | the toolchain directory as the toolchain of a build, for the host or `XCLANG_TARGET` | +| `runtimes.cmake` | included by `toolchain.cmake`: the runtimes built from source, and the build's sanitizers (from the release after 23.1.2.10) | +| `runtimes-cxx.cmake`, `runtimes-compiler-rt.cmake` | the CMake caches of xclang's own builds of libc++ and compiler-rt, which `runtimes.cmake` builds with | | `xclang.cmake` | in `packages/cmake/` only: included before `project()` from a FetchContent checkout, it downloads the toolchain | ## `find_package(xclang)` @@ -33,7 +35,9 @@ must be xclang's `clang++`. It finds the package through `PATH` | `XCLANG_THINLTO_CACHE` | cache variable | an absolute directory for the ThinLTO cache of the linker; its first value comes from the environment variable of the same name ([the ThinLTO cache](../features/thinlto-cache.md#usage)) | `xclang::std` asks its importers for C++23, or for the `CMAKE_CXX_STANDARD` -it was built with if that is 20 or later. +it was built with if that is 20 or later. With `XCLANG_RUNTIMES=source`, it +is built from the variant's modules and headers; that option needs the +toolchain file, and `find_package(xclang)` fails without it. ## `toolchain.cmake` @@ -46,6 +50,7 @@ cmake -G Ninja -B build --toolchain $XCLANG/lib/cmake/xclang/toolchain.cmake [-D | `XCLANG_TARGET` | `x86_64-unknown-linux-gnu`, `aarch64-unknown-linux-gnu`, `x86_64-unknown-linux-musl`, `aarch64-unknown-linux-musl`, `x86_64-w64-mingw32`, `aarch64-w64-mingw32`, `aarch64-apple-darwin`, `x86_64-apple-darwin`, `x86_64-pc-windows-msvc` or `aarch64-pc-windows-msvc`; the host's by default. The MSVC targets, and the macOS targets on Linux and Windows hosts, build with the SDK that the toolchain's `xclang` fetched. The musl targets, from 23.1.2.10 on, are no cross build on a Linux host of their architecture, which runs their static programs (`try_run`, tests) | | `XCLANG_ROOT` | the toolchain directory, when the file is used from outside one | | `XCLANG_MSVC_STL` | `ON`: an MSVC target's C++ library is Microsoft's STL, not libc++ (`-stdlib=platform` in `CMAKE_CXX_FLAGS`), and `xclang::std` the STL's; ignored for other targets | +| `XCLANG_RUNTIMES`, `XCLANG_SANITIZER`, ... | the runtimes built from source and the build's sanitizers ([below](#runtimes-from-source)) | It sets the C, C++ and ASM compilers, and the binary tools, to those of the toolchain directory: `llvm-ar`, `llvm-ranlib`, `llvm-nm`, `llvm-objcopy`, @@ -81,6 +86,38 @@ stops if that has no SDK. It sets `CMAKE_SYSTEM_NAME` to `Darwin`, `x86_64`, `CMAKE__COMPILER_TARGET` (C, C++, ASM, Objective-C), and the SDK as `CMAKE_FIND_ROOT_PATH`, with the modes above. +### Runtimes from Source + +In no release yet ([Unreleased](../design/roadmap.md#libc-on-demand)). +`runtimes.cmake`, which the toolchain file includes, reads these +variables ([runtimes from source](../features/runtimes-from-source.md)): + +| variable | | +|---|---| +| `XCLANG_RUNTIMES` | `prebuilt`, the default: the toolchain's runtimes. `source`: libc++ (with libc++abi), libc++experimental and libunwind built from the toolchain's `libc++/src` for the target, with the options below, at the first configure that asks for the variant; every compile and link of the build is against them in place of the prebuilt ones, `try_compile`'s too. Not for the MSVC targets | +| `XCLANG_SANITIZER` | a list of `address`, `memory`, `thread`, `undefined`, `leak`: `-fsanitize=` on every compile and link of the build, and runtimes that suit it. With the prebuilt runtimes, `address` adds the ASan libc++ where the target has one, and `memory` stops the configure; with `source`, the runtimes are built with the sanitizers (`LLVM_USE_SANITIZER`), and `memory` builds compiler-rt's MemorySanitizer runtime too, linked into executables | +| `XCLANG_LIBCXX_HARDENING` | `none`, `fast`, `extensive` or `debug`: libc++'s hardening mode (`LIBCXX_HARDENING_MODE`), of the library and the default of its headers | +| `XCLANG_LIBCXX_ABI_VERSION` | `1` or `2` (`LIBCXX_ABI_VERSION`) | +| `XCLANG_LIBCXX_ABI_NAMESPACE` | libc++'s inline namespace, `__` (`LIBCXX_ABI_NAMESPACE`) | +| `XCLANG_LIBCXX_ABI_DEFINES` | a list of libc++'s ABI macros, such as `_LIBCPP_ABI_BOUNDED_ITERATORS` (`LIBCXX_ABI_DEFINES`) | +| `XCLANG_RUNTIMES_EXCEPTIONS` | `OFF`: libc++ and libc++abi without exceptions | +| `XCLANG_RUNTIMES_RTTI` | `OFF`: libc++ without RTTI; needs `XCLANG_RUNTIMES_EXCEPTIONS=OFF` | +| `XCLANG_RUNTIMES_FLAGS` | more compile options of libc++ and libc++abi, such as `-flto=thin` | +| `XCLANG_RUNTIMES_CMAKE_ARGS` | more arguments of the runtimes' CMake build, LLVM's `runtimes/`, `-D=` each | +| `XCLANG_RUNTIMES_DIR` | where the variants are built, `-` each; `${CMAKE_BINARY_DIR}/xclang-runtimes` by default | + +The options but `XCLANG_RUNTIMES` and `XCLANG_SANITIZER` need +`XCLANG_RUNTIMES=source`. A variant's directory holds its CMake builds +(`runtimes`, and with MemorySanitizer `compiler-rt`), their logs, and +`install`: `include/c++/v1`, the headers, `__config_site` among them, which +come before the config file's with `-nostdinc++`; `lib`, the libraries, +linked with `-nostdlib++` and, but for macOS and with sanitizers, +`--unwindlib=none`; `lib/libc++.modules.json` and `share/libc++/v1`, the +modules of `xclang::std`. Its name is a digest of the options, the target +and the toolchain, so a variant is built once per build directory, and +another set of options builds another beside it. The build needs Python +3, as LLVM's does. + ## `xclang.cmake` Included before `project()`, from a FetchContent checkout of the tag of a diff --git a/en/xclang/reference/layout.md b/en/xclang/reference/layout.md index 6d0916b34..3db7d2e88 100644 --- a/en/xclang/reference/layout.md +++ b/en/xclang/reference/layout.md @@ -24,6 +24,9 @@ xclang/ libc++/include//c++/v1/ each target's own __config_site, as clang spells it (x86_64-w64-windows-gnu) + libc++/src/ the runtimes' sources, the same for every target, + in llvm-project's layout, patched (below); in the + releases after 23.1.2.10 mingw-w64/include/ mingw-w64's headers, the same for both Windows targets share/licenses/ the license notices of everything in the archive @@ -81,6 +84,17 @@ SDK's, so `--no-default-config` would find xclang's headers without a `__config_site` there instead of the system's. Before 23.1.2.7 each target directory had its own copies, 155 MB of the 800 MB unpacked. +## The Runtimes' Sources + +`libc++/src` holds what the runtimes of every target are built from, once: +llvm-project's `runtimes/`, `cmake/`, `llvm/cmake/`, `libcxx/`, +`libcxxabi/`, `libunwind/` and `compiler-rt/`, without tests and +documentation, and the headers of LLVM's libc that libc++ includes, with +xclang's patches of them applied. The CMake package and the Bazel module +build the runtimes from them ([runtimes from source](../features/runtimes-from-source.md)), +LLVM's `runtimes/` as from a checkout. They are 35 MB unpacked, in the +releases after 23.1.2.10. + ## Licenses Every archive, the toolchain, libclang, the ASan libclang and the option diff --git a/en/xclang/sidebar.yaml b/en/xclang/sidebar.yaml index a19137a9d..817b53173 100644 --- a/en/xclang/sidebar.yaml +++ b/en/xclang/sidebar.yaml @@ -32,6 +32,8 @@ features: - file: modules label: Modules - sanitizers + - file: runtimes-from-source + label: Runtimes from Source - file: debugging label: Debugging - file: libclang