# CST-agent on Android The engine runs on the phone as a plain bionic binary -- no Termux, no proot, no second process for the UI to talk to. It is the same C core the CLI, the TUI and the WebUI use, cross-compiled with the NDK; on the phone the Qt front end (app/) will link `libcstcore.a` in-process and register its own platform tools under the owner `app:android`. Two scripts cover the engine side: | script | what it does | | --- | --- | | `scripts/build_third_party_android.sh ABI [all\|mbedtls\|curl]` | static mbedTLS + libcurl into `third_party/prefix-android-ABI` | | `scripts/build_android.sh [ABI] [--push] [--run] [--run-tests]` | `libcstcore.a`, `cst-agent`, the test binaries; optional push and on-device run | ## Toolchain NixOS: nixpkgs carries the NDK (the Android SDK license makes it unfree, hence the flag; the packaged NDK has a patched interpreter, so its clang runs here): ```sh export ANDROID_NDK_HOME=$(NIXPKGS_ALLOW_UNFREE=1 nix build --impure --no-link \ --print-out-paths 'nixpkgs#androidenv.androidPkgs.ndk-bundle')/libexec/android-sdk/ndk-bundle ``` `adb` comes from `nix-shell -p android-tools`; the builds need cmake, ninja and curl. End to end: ```sh nix-shell -p cmake ninja curl android-tools --run ' JOBS=16 ./scripts/build_third_party_android.sh arm64-v8a all' nix-shell -p cmake ninja curl android-tools --run ' JOBS=16 ./scripts/build_android.sh arm64-v8a --push --run' ``` `--run` finishes with the two smoke checks on the device (`cst-agent --version` and `tests/test_embed`, the in-process embedding contract); `--run-tests` builds the whole `tests/` suite, pushes it and runs every binary on the phone, printing a pass/fail line per test. ## What is Android-specific * **API level 24** (`API_LEVEL=24`): bionic provides threads, `exec` and `/system/etc/security/cacerts`, which is where libcurl is pointed (`CURL_CA_PATH`). Bump the level if a newer syscall or CA layout is needed. * **No TUI, no WebUI**: `-DCST_BUILD_TUI=OFF -DCST_BUILD_WEBUI=OFF` -- there is no ncurses on Android, and the phone front end talks to the engine in-process instead of over HTTP. `src/webui_stub.c` compiles in place of the server. * **Sandbox**: `src/sandbox_exec.c` only enables the seccomp/Landlock paths under `defined(__linux__) && !defined(__ANDROID__)`, so the phone build gets the plain exec path -- the same rule the Termux build follows. The seccomp supervisor used to compile in and the probe reported "seccomp", but on the device a write outside the workspace was not denied (`tests/test_sandbox.c:308`), so the phone build now reports no sandbox instead of one that does not hold. * **sashidown** is built per ABI (`vendor/sashidown/libsashidown-.a`) with the NDK's `aarch64-linux-android24-clang` wrapper: CMake's compiler is plain clang and keeps `--target`/`--sysroot` in its own variables, which the vendored makefile cannot see. The host archive stays host-built. * **Static libcurl** needs `-L$PREFIX/lib` on the link line, because curl's own CMake config lists its mbedTLS dependencies as `-l` flags rather than paths. ## Status * arm64-v8a, Android 16 (NX789J): `cst-agent` runs, `tests/test_embed` passes. * The whole suite runs on the device (`scripts/build_android.sh arm64-v8a --run-tests`): 36/36 after the diff test learned to tell toybox's `diff` from GNU diffutils. * Still to come: the Qt front end packaged as an APK. nixpkgs has no Qt for Android build, so that needs a Qt host kit plus the `android_arm64_v8a` kit (qt.io or aqtinstall), a JDK and the Android SDK platform/build-tools; `app/src/platform/android/` (JNI tools, owner `app:android`) and the Gradle project under `app/android/` do not exist yet.