Build the host SDK and Python wheel¶
Use CMake/Ninja presets for native builds, GTest for native tests and Pytest for Python and integration tests. Install prerequisites from the macOS and Linux source guide.
Build and test from a checkout¶
export SYMBIAN_DEPS_PREFIX="$PWD/.symbian/host-deps"
scripts/bootstrap_wheel_deps.sh
cmake --preset debug
cmake --build --preset debug --parallel 4
ctest --preset debug
uv sync
uv run pytest -q
uv build --wheel
The isolated prefix supplies static OpenSSL, libusb, Boost and zlib.
Abseil, nlohmann::json and pybind11_abseil use pinned source revisions;
source-directory overrides allow prepared offline inputs. On Linux the
bootstrap also needs Perl's IPC::Cmd and Time::Piece modules.
Native libraries default to exceptions disabled. Selected Boost implementation and pybind11 translation units explicitly enable exceptions where required. Linux hides statically linked vendor symbols.
build/debug/compile_commands.json contains host commands and, when the source
SDK is prepared, the configured GUI's ARM commands. Host and guest builds use
separate target configurations. See CLion setup and the
guest runtime.
Check an installed wheel¶
Install a built wheel into a fresh environment and run the audit outside the checkout:
python -m venv /tmp/symbian-wheel-check
/tmp/symbian-wheel-check/bin/pip install /absolute/path/to/the.whl
cd /tmp
/tmp/symbian-wheel-check/bin/python -m symbian.build_support.audit \
/absolute/path/to/the.whl
The audit checks Mach-O/ELF dependency closure, native imports, structured
statuses, CLI tools and packaged resources. Linux distribution wheels also
require manylinux repair and tagging; a local linux_x86_64 or
linux_aarch64 wheel is not automatically a manylinux wheel.
The host tooling wheel does not include firmware. Prepare the native target SDK separately using SDK installation.
Install a standalone C++ host SDK¶
Configure the host install explicitly. The prefix contains headers, one static
archive with its private dependency closure, CMake configuration, licenses and
symbian-native. It does not include the ARM guest SDK or firmware.
export SYMBIAN_DEPS_PREFIX="$PWD/.symbian/host-deps"
scripts/bootstrap_wheel_deps.sh
cmake --preset release -DSYMBIAN_INSTALL_HOST_SDK=ON \
-DCMAKE_INSTALL_PREFIX="$PWD/.symbian/host-sdk"
cmake --build --preset release --parallel 4
ctest --preset release
cmake --install build/release
uv run python scripts/check_host_sdk.py .symbian/host-sdk
The installed prefix can move without rebasing its CMake configuration. An
ordinary consumer needs only the host compiler, CMake and OS thread/system
libraries; it does not need separate Boost, Abseil, OpenSSL, libusb or zlib
installations. For a directory containing main.cc and CMakeLists.txt:
cmake_minimum_required(VERSION 3.28)
project(export_reader LANGUAGES CXX)
find_package(SymbianHost CONFIG REQUIRED)
add_executable(export_reader main.cc)
target_link_libraries(export_reader PRIVATE Symbian::Host)
#include <iostream>
#include "symbian/sdk/exports.h"
int main() {
auto exports = symbian::sdk::ParseExports("EXPORTS\nExample @ 7 NONAME\n");
if (!exports.ok()) {
std::cerr << exports.status() << '\n';
return 1;
}
std::cout << exports->front().ordinal << '\n';
return 0;
}
cmake -S . -B build -G Ninja -DCMAKE_PREFIX_PATH=/absolute/host-sdk
cmake --build build
./build/export_reader
Publish a native image without Python¶
symbian-native calls the same native format implementation as the Python
CLI. It converts a linked guest ELF and generates import-proxy sources:
/absolute/host-sdk/bin/symbian-native convert-exe \
--input app.elf --uid3 0xE0000808 --output app.exe \
--import-proxy /absolute/sdk/proxies/euser/euser.dso
/absolute/host-sdk/bin/symbian-native proxy-sources \
--definition euser.def --symbol _ZN4User4ExitEi \
--target-dll euser.dll --output generated-proxy
Declare every import proxy used by the ELF. For an import-free image, omit
--import-proxy; for the legacy process profile, add --kernel eka1 and use
compatible GNU2 proxies. convert-dll additionally requires --definition
with frozen exports; EKA1 DLL publication is unsupported.
Proxy generation writes exports.S, exports.map and proxy.ld for the ARM
compiler/linker. The installed SymbianPic helper uses this native tool when
available. Conversion rejects unsupported ELF profiles, and output paths that
alias an input are rejected before publication. Inputs are limited to 64 MiB.
Reuse the host archive across Python builds¶
After installing the C++ host SDK, build only the Python binding layer for each
interpreter. Select the prefix with SYMBIAN_PREBUILT_HOST_SDK:
CMAKE_ARGS="-DSYMBIAN_PREBUILT_HOST_SDK=$PWD/.symbian/host-sdk" \
uv build --python 3.12 --wheel --out-dir dist
The prefix must match the source version, OS, architecture, C++ ABI and deployment
target. Build separate binding wheels for each Python version; the host archive
is reused. On macOS, set the same MACOSX_DEPLOYMENT_TARGET when building the
static dependencies, host SDK and binding wheels. Audit each installed wheel as
shown above.