Skip to content

Prepare the toolchain and public source

Run these commands from the repository root. The host tools compile C++ and convert ARM ELF into Symbian E32; target headers and firmware are separate inputs. Follow the tab for your host system below.

1. Install host tools

On Apple Silicon, install Apple's command-line tools if xcrun does not find Clang. Homebrew supplies CMake, Ninja, upstream LLVM/LLD and uv:

xcode-select -p
xcrun --find clang++
brew install uv cmake ninja lld llvm googletest openssl@3

On Ubuntu 24.04 or a comparable distribution, install a C++ toolchain, CMake 3.28+, Ninja 1.12+, Clang/LLD and the bootstrap prerequisites. Package names can vary by distribution.

sudo apt update
sudo apt install build-essential clang clang-format lld llvm cmake ninja-build \
  git curl ca-certificates perl pkg-config autoconf automake libtool \
  python3-dev python3-tk
curl -LsSf https://astral.sh/uv/install.sh | sh

Ubuntu 24.04's Ninja 1.11 is too old for target input tracking. Install the maintained version and put its directory first on PATH:

uv tool install 'ninja>=1.12,<2'
export PATH="$HOME/.local/bin:$PATH"

Host format libraries require a C++20 compiler. The pinned LLVM 23 libc++ guest sources require Clang 23 or later, with matching LLD, archive tools and clang-scan-deps. Select that toolchain before SDK export. Official LLVM Linux binaries may require older ICU shared libraries; check ldd on every tool and install any missing runtime libraries.

If you have installed a native SDK archive, you can use its bundled LLVM, CMake and Ninja for source builds and tests:

export SYMBIAN_LLVM_BIN="$HOME/dev/symbian-sdk/bin"
export PATH="$SYMBIAN_LLVM_BIN:$HOME/.local/bin:$PATH"
clang++ --version
ld.lld --version

Start a new shell if the uv installer added its directory to your PATH. The uv installer also supports a pinned-version URL.

2. Prepare the host build and check ARM output

Use an isolated prefix for static OpenSSL, libusb and Boost, following the same native/wheel separation as A11. The bootstrap checks the source archive hashes. The export/build tools require clang, clang++, ld.lld, llvm-ar and llvm-ranlib; put one LLVM toolchain on PATH, or set SYMBIAN_LLVM_BIN to its bin directory for SDK export.

export SYMBIAN_DEPS_PREFIX="$PWD/.symbian/host-deps"
scripts/bootstrap_wheel_deps.sh
uv sync
source .venv/bin/activate
symbian doctor
symbian toolchain probe

Build the GUI source example after preparing its headers below and selecting an installed SDK:

symbian build --project examples/gui_app \
  --output .symbian/gui-app \
  --compiler "$(command -v clang++)" --linker "$(command -v ld.lld)"

The report records the actual compiler and linker. Independent builds on one host check reproducibility for that toolchain; they do not prove identical output across macOS and Linux. symbian init defaults to ARMv6 and can select ARMv5T explicitly. The cross toolchain supplies freestanding ARM EABI flags and target include paths, so host C++ headers do not enter a guest build.

A working ARM build does not prove E32 loader acceptance, emulator execution or Nokia 808 compatibility. The host build guide covers native tests and wheel checks; C++20 capabilities records the bounded guest runtime.

3. Acquire the pinned public source profile

The checked-in manifest contains paths, hashes, revisions, and export names. It does not contain an SDK distribution or upstream header contents. For a fresh workspace acquire these exact public repositories, retaining their licenses. These commands create ignored research checkouts:

mkdir -p research/upstream
git clone --filter=blob:none --no-checkout \
  https://github.com/SymbianSource/oss.FCL.sf.os.kernelhwsrv \
  research/upstream/kernelhwsrv
git -C research/upstream/kernelhwsrv checkout \
  0c3208650587ac0230aed8a74e9bddb5288023eb
git clone --filter=blob:none --no-checkout \
  https://github.com/SymbianSource/oss.FCL.sf.os.graphics \
  research/upstream/graphics
git -C research/upstream/graphics checkout \
  ff133bc50e6158bfb08cc093b0f0055321dcde99
git clone --filter=blob:none --no-checkout \
  https://github.com/SymbianSource/oss.FCL.sf.os.ossrv \
  research/upstream/ossrv
git -C research/upstream/ossrv checkout \
  1e9520caca186c601dd9768449b86bc72be39a22
git clone --filter=blob:none --no-checkout \
  https://github.com/SymbianSource/oss.FCL.sf.os.persistentdata \
  research/upstream/persistentdata
git -C research/upstream/persistentdata checkout \
  ef8baa21cee9cd1e214e1a7986595c60b3a63271
git clone --filter=blob:none --no-checkout \
  https://github.com/SymbianSource/oss.FCL.sf.os.textandloc \
  research/upstream/textandloc
git -C research/upstream/textandloc checkout \
  59666d6704fee305b0fdd74974f7b4f42659c6a6

If a checkout already exists, use git -C <directory> rev-parse HEAD and git -C <directory> status --short to inspect it; skip the corresponding clone. Do not reset local research changes to follow this recipe. A sparse checkout must contain every file named by the research source profile, including differently cased INC/inc directories and private header dependencies. A full checkout is the straightforward starting point.

Prepare the source profile:

symbian toolchain prepare-gui-sdk \
  --profile research/gui_app/source-profile.json \
  --sources-root research/upstream \
  --output .symbian/gui-sdk

Preparation verifies each actual input's SHA-256, creates explicit header aliases as symlinks into the original checkouts, validates the original narrow import selection in the native core, and builds two reproducible ordinal proxies. The migrated GUI uses the installed SDK's broader proxies at link time. It refuses path escapes, different occupied headers, and redirected output directories. The 93 aliases flatten SDK includes and preserve necessary graphics/... namespaces without modifying upstream files. Reported repository revisions are manifest declarations; preparation verifies file digests, not Git provenance. Keep original licenses beside the source trees and retain those trees for as long as the aliases are used. Symlinks are not a preserved independent copy.

The EUSER definition is kernel/eka/eabi/euseru.def; WS32 is windowing/windowserver/eabi/WS322U.DEF. The native parser selects the 38 frozen function ordinals without renumbering. The generated euser.dso and ws32.dso are link-time ordinal proxies, not executable implementations of those libraries. Copying them into a guest cannot supply EUSER or Window Server. These headers and export definitions describe a pre-Belle source profile. The target firmware must supply compatible system DLLs and services.

The preparation report is .symbian/gui-sdk/sdk-report.json; each proxy also retains its own source, build trees, input digests and report.json.

4. Prepare the runtime and SDK sources

To build an installed native SDK, also acquire the runtime, camera and application-resource sources. The following commands supplement the five platform checkouts above; skip clones for checkouts you already prepared.

git clone --filter=blob:none --no-checkout \
  https://github.com/llvm/llvm-project.git research/upstream/llvm-project
git -C research/upstream/llvm-project checkout \
  85ac560262434c9ccfc0c183ec22d4138ed647fb
git clone --filter=blob:none --no-checkout \
  https://github.com/abseil/abseil-cpp.git research/upstream/abseil-cpp
git -C research/upstream/abseil-cpp checkout \
  5650e9cf76d3be4318d5fa3af38ee483ddfd5e4a
git clone --filter=blob:none --no-checkout \
  https://github.com/microsoft/mimalloc.git research/upstream/mimalloc
git -C research/upstream/mimalloc checkout \
  d4881d338125e1cb7c47ba4cfb398d6f7c0c8d45
git clone --filter=blob:none --no-checkout \
  https://github.com/SymbianSource/oss.FCL.sf.os.mm.git research/upstream/mm
git -C research/upstream/mm checkout \
  ebaa78373866f90dbf706e8d4eeb59ff65f1e107
git clone --filter=blob:none --no-checkout \
  https://github.com/SymbianSource/oss.FCL.sf.mw.appsupport.git \
  research/upstream/appsupport
git -C research/upstream/appsupport checkout \
  3efd2b6c5ad920873846770a70f9769721e494c8
git clone --filter=blob:none --no-checkout \
  https://github.com/nghttp2/nghttp2.git third_party/nghttp2
git -C third_party/nghttp2 checkout \
  85e300c79fb6dbcfa9c1013215c8710c1c2cd3d2
mkdir -p .symbian
git clone --filter=blob:none --no-checkout \
  https://github.com/SymbianRevive/symbian-build.git .symbian/rcomp-epl-research
git -C .symbian/rcomp-epl-research checkout \
  d3c2eadd3ff7826bdf9e1d92f447c357571af18b

Apply the three maintained LLVM source patches from the repository root. They supply the Symbian clock and atomic contracts and ARMv5-compatible software floating-point instructions:

git -C research/upstream/llvm-project apply \
  ../../../research/llvm/symbian-libcxx-lock-free.patch
git -C research/upstream/llvm-project apply \
  ../../../research/llvm/symbian-libcxx-chrono.patch
git -C research/upstream/llvm-project apply \
  ../../../research/llvm/symbian-compiler-rt-armv5-softdouble.patch

Apply each patch once. To check an existing patched checkout, use git apply --reverse --check with the same path; preserve any other local changes. SDK installation builds the resource compiler with its maintained host patch and copies its licence alongside the installed tool.

With the host tools installed, Clang 23 selected and the GUI headers staged:

symbian sdk install ~/dev/symbian-sdk --workspace "$PWD"
symbian init ~/dev/hello_time --name hello_time --non-interactive
symbian app build --project ~/dev/hello_time

The SDK provides target headers, static libraries, ordinal proxies and build tools. System services still come from the target firmware. For packaging, signing and installation on a device, continue with Build an application.