CRT is a Bionic-compatible cross-platform C runtime and Platform Adaptation Layer (PAL). It lets Linux/BSD/Android-style native libraries and applications be rebuilt from the same source as native Linux, Windows, and macOS executables.
The primary target is a Linux-kernel embedded device: set-top boxes, Raspberry-Pi-class consoles, industrial HMIs, and automotive IVI systems. Native desktop builds provide a fast development and debugging loop and can also be shipped as desktop applications.
CRT owns the low-level portability boundary: files, sockets, threads, TLS, memory mapping, clocks, signals, process basics, dynamic-loading policy, startup objects, libc/libm/libdl, and the C++ runtime. Higher layers add a window/input/software-framebuffer API, accelerated graphics and media, and a JavaScript runtime.
The compatibility model is source rebuilding against a Bionic-shaped public surface. CRT does not aim to run unmodified glibc binaries or APKs, reproduce Android Framework, provide a container/VM, or directly port Qt, GTK, Enlightenment, Chromium, or Electron.
The linker/ directory is retained for a possible future CRT-owned loader,
but linker implementation is outside the current roadmap.
Clang/LLVM, LLD, and compiler-rt are the primary development toolchain, but CRT distributions never bundle a compiler or linker. Embedded devices use their vendor/dedicated toolchain. A distribution contains the CRT sysroot, startup objects, runtime libraries, wrappers, CMake configuration, and a manifest that records the external toolchain contract.
The Windows C++ lane uses the Bionic/Itanium ABI and project-built libunwind.
Windows C++ exceptions are compiled as DWARF CFI (-fdwarf-exceptions) rather
than depending on the OS-owned SEH unwind engine. See
docs/cxx_runtime.md.
CRT is built and verified as cumulative distributions:
| Stage | Advertised surface |
|---|---|
01-c |
libc/libm/libdl, startup, shell, mksh, toybox, awk, make |
02-cxx |
01-c + libc++/libc++abi/libunwind |
03-gfx-simple |
02-cxx + window, keyboard/mouse, software framebuffer |
04-gfx-media |
03-gfx-simple + Skia CPU/GPU, Vulkan/D3D12/Metal, FFmpeg |
05-js |
04-gfx-media + JavaScript runtime/bindings layer |
Simple Graphics deliberately excludes Skia CPU raster/text and Skia GPU. Its
drawing surface is the CPU-writable framebuffer in crtgfx/window.h.
The normal repository build proves that every later binary package inherits
the preceding installed dist tree. The stronger source-stage boundary is
also implemented: a packaged predecessor SDK fetches a SHA-256-pinned CRT
GitHub Release source asset and builds/tests the next stage without using the
repository build tree. 02-cxx -> 03-gfx-simple is verified on all three
hosts; the complete 01-c -> 02-cxx -> 03-gfx-simple chain is explicitly
recorded on Windows and macOS; and the option-ON 03-gfx-simple -> 04-gfx-media transition is complete on Windows and macOS, with Linux final
example/verification/publication checks still open. 04-gfx-media -> 05-js
has not yet been added. Full details, artifact layout, package naming, and
acceptance rules are in
docs/distribution.md.
The current 05-js package contains the installable libcrtjs skeleton. The
QuickJS engine, event loop, modules, and JavaScript-visible graphics/media
bindings remain planned work rather than a current completion claim. Likewise,
the ordinary developer preset keeps Skia and FFmpeg disabled by default;
release-grade 04-gfx-media acceptance uses the separate option-ON isolated
stage path.
Release engineering creates an OS-qualified upper-stage source asset and its recipe only after the component sources have been fetched at their pinned revisions. For example:
python3 tools/create_stage_source.py --root . --stage 02-cxx \
--target-os <linux|macos|windows> \
--source-root out/<preset>/external/llvm-runtimes \
--output-dir out/<preset>/stage-sources --release-tag <tag>The command emits a deterministic source archive plus a recipe containing its
target OS, exact byte size, CRT commit, and SHA-256. Asset names include the
target OS because source payloads differ by backend. After the asset and recipe
are published, an extracted predecessor SDK consumes them with its packaged
tools/crt-stage-build.py; a local --asset override is available for
pre-publication acceptance without weakening digest verification.
All hosts need Git, CMake 3.25+, Ninja, Python 3, Clang, LLD, and suitable archive tools. These are build-machine prerequisites, not distribution contents.
For Debian/Ubuntu, a representative base setup is:
sudo apt install git cmake ninja-build python3 clang lld compiler-rtSimple Graphics additionally needs a running Wayland compositor and the Wayland/xkbcommon runtime. Advanced graphics normally adds:
sudo apt install libvulkan-dev libwayland-dev mesa-vulkan-drivers vulkan-toolsmesa-vulkan-drivers may be replaced with the GPU vendor's Vulkan ICD. The
current Linux FFmpeg recipe does not enable VA-API. When that path is enabled,
the usual development/runtime set is libva-dev, libva2, libva-drm2, a
vendor VA driver, and optional vainfo. Embedded images should satisfy the
same capabilities with board-vendor packages rather than copying desktop
package lists.
Install Git, CMake, Ninja, Python, LLVM for Windows, and a Windows 10/11 SDK.
Run CMake from a shell where the SDK import libraries are discoverable. The
CRT Windows target is *-w64-mingw32 for the common Itanium ABI lane even
though the host SDK supplies the native system and graphics import libraries.
Install Xcode Command Line Tools, CMake, Ninja, and Python 3. Metal and the required system frameworks come from the platform SDK.
The default workflow configures, builds, and tests only the C stage:
cmake --workflow --preset linux-host-ninja-debug
cmake --workflow --preset macos-host-ninja-debug
cmake --workflow --preset windows-host-ninja-debugFocused stage commands use the matching build preset:
cmake --build --preset <preset> --target crt-c-build
cmake --build --preset <preset> --target crt-c-test
cmake --build --preset <preset> --target crt-c-dist
cmake --build --preset <preset> --target crt-libcxx-build
cmake --build --preset <preset> --target crt-libcxx-test
cmake --build --preset <preset> --target crt-libcxx-dist
cmake --build --preset <preset> --target crt-gfx-simple-build
cmake --build --preset <preset> --target crt-gfx-simple-test
cmake --build --preset <preset> --target crt-gfx-simple-dist
cmake --build --preset <preset> --target crt-gfx-media-build
cmake --build --preset <preset> --target crt-gfx-media-test
cmake --build --preset <preset> --target crt-gfx-media-dist
cmake --build --preset <preset> --target crt-js-build
cmake --build --preset <preset> --target crt-js-test
cmake --build --preset <preset> --target crt-js-distThe outputs are cumulative directories and archives under
out/<preset>/dist/. A later *-dist target builds preceding stages as
dependencies. This dependency establishes cumulative package contents; the
source-stage bootstrap commands described above will separately verify that a
freshly extracted predecessor SDK can produce the next stage without reading
repository headers, libraries, or build outputs.
A stage is a self-contained sysroot for its advertised surface. Its
include/, lib/, and Windows bin/ directories therefore include the
redistributable headers, link artifacts, and .so/.dylib/.dll runtime
files of external libraries required by that stage, not only CRT-owned files.
OS frameworks/system libraries and device-specific GPU/video drivers are
documented manifest prerequisites instead of silently copied or assumed. The
exact transitive packaging and licensing rule is in
docs/distribution.md.
Advanced graphics must be configured with a completed imported libc++ and
Skia build. The existing crtgfx-skia-fetch, crtgfx-skia-configure,
crtgfx-skia-build, and crtgfx-skia-smoke targets retain that explicit
bring-up path. FFmpeg remains controlled by CRTMEDIA_ENABLE_FFMPEG.
Select a stage, then provide the external compiler tools:
export CRT_CC=/path/to/clang
export CRT_CXX=/path/to/clang++
export CRT_AR=/path/to/llvm-ar
export CRT_RANLIB=/path/to/llvm-ranlib
. out/<preset>/dist/02-cxx/activate.shOn Windows use call out\<preset>\dist\02-cxx\activate.cmd. CMake consumers
may use the packaged crt-toolchain.cmake, which selects the packaged wrappers.
An embedded vendor toolchain that cannot use those Clang-compatible wrappers
should remain authoritative and consume CRT's packaged sysroot directly.
The Windows activation script discovers the SDK import-library directory from
a Developer Command Prompt, or accepts an explicit CRT_WINDOWS_SDK_LIBPATH.
The in-repository wrappers tools/crt-cc and tools/crt-c++ enforce the
freestanding/sysroot/default-runtime boundary. Every stage also packages
optional Python port fetch/build drivers, pinned recipes, tests/shims, and the
examples appropriate to that stage. Configure/make work runs through the
packaged CRT mksh and Toybox tools; MSYS and Git Bash are not distribution
prerequisites. Upstream sources are not patched merely to hide a missing CRT
surface; the missing Bionic API/type/symbol/behavior is implemented in CRT
first.
include/ Bionic-compatible public headers
libc/ libc, PAL, startup, OS/architecture backends
libm/ math runtime
libdl/ dynamic-loading API and host backends
libstdc++/ bootstrap ABI shim and imported libc++ build integration
shell/ tiny shell, mksh, toybox, and awk
libcrtgfx/ window/input/framebuffer and advanced Skia/GPU integration
libcrtmedia/ media runtime and optional FFmpeg integration
libcrtjs/ JavaScript runtime skeleton; QuickJS integration is planned
porting/recipes/ upstream porting test recipes
tools/ wrappers, rootfs/dist builders, porting automation
libc/tests/ libc, PAL, shell-level, ABI, and integration tests
libstdc++/tests/ C/C++ ABI-boundary tests
libcrtgfx/tests/ window, input, software, GPU, and Skia tests
libcrtmedia/tests/ frame, codec, player, audio, and FFmpeg tests
docs/ design, policy, roadmap, and verification documents
- Project meaning
- Stack and toolchain policy
- Distribution stages
- Runtime roadmap
- C++ runtime
- Graphics API policy
- Media API policy
- Sysroot porting
- Current status, work queue, and history
Project-owned code and imported upstream families retain their applicable
license and provenance records. Bionic/OpenBSD imports are tracked under
third_party/; external runtime, graphics, media, shell, and porting sources
have project-owned recipe or import metadata next to their integration.