toolchain, doctor, device, emulator
The machine and the phones: what Whitehall manages, what it found, and the raw tools it hands you.
doctor
whitehall doctor [manifest] What this machine has, and what to type next. It reads the disk and downloads nothing, so a missing thing is a line, not a wait. It says which door the directory is — an app, a tool, or neither — and the one command that opens it. Run it first, and run it when something is wrong.
Found the Android SDK and adb in ~/.whitehall/toolchains/android
Found the NDK 26.1.10909125
Found CPython 3.13.9-0 for arm64-v8a
Device Pixel · 1A2B3C4D5E6F7G
Here a tool — Cargo.toml
whitehall shell then `cargo run`, on the phone manifest is a directory or a path to a whitehall.toml; the default
is here.
toolchain
Java, Gradle, the Android SDK and NDK, kotlinc, CPython and Go are downloaded
on first use into ~/.whitehall/toolchains/, shared across projects and
version-isolated. These verbs manage that cache.
| Command | What it does |
|---|---|
toolchain install [manifest] | Install what this project needs: Java, Gradle, Android SDK, emulator, system images. Go too, but only in a directory that has Go in it |
toolchain list [manifest] | List what is installed as a tree, marking what this project uses |
toolchain outdated | Report which SDK packages are behind. Installs nothing |
toolchain update | Install newer SDK packages: the ones with no version in their name — platform-tools (which is adb), emulator, cmdline-tools |
toolchain update --latest | Also install the newest build-tools and platform, past the pin |
toolchain available [filter] | Show every SDK package the repository offers, and pick one to install. Installs it, changes no manifest |
toolchain clean | Remove all installed toolchains |
toolchain exec, toolchain shell | The toolchain environment alone, without the Android target |
whitehall toolchain outdated # what is behind, installing nothing
whitehall toolchain update # adb, the emulator, cmdline-tools
whitehall toolchain available build-tools update --latest puts the newer packages on disk, but the versions a build uses
are pinned in versions.toml, compiled into Whitehall. The build keeps using the
pinned versions until a release moves them.device
whitehall device [list | pin <query> | unpin | package] $ whitehall device
Device Pixel · 1A2B3C4D5E6F7G | Command | What it does |
|---|---|
device, device list | List connected devices. Aliases devices, ls |
device pin <query> | Pin a device, so every verb goes there without -d. query is a serial, the start of one, or the model name |
device unpin | Forget the pin |
device package [-a] | What is installed on the phone, with this machine's images marked. -a adds Android's own packages. Alias packages |
Which phone a verb goes to
The same rule everywhere, most specific first:
| Source | |
|---|---|
| 1 | -d <query> — a serial, the start of one, or the model name; case and punctuation ignored. Two matches is a refusal that lists them |
| 2 | $ANDROID_SERIAL |
| 3 | whitehall device pin. Pinned but not attached is an error, never a quiet fallback to the other phone |
| 4 | the only one attached |
| 5 | a menu, when more than one is attached and nothing above chose |
The menu is the default at a terminal. --non-interactive (a global flag), the WHITEHALL_NON_INTERACTIVE or CI environment variables, or not being
at a terminal turn it into the list and a non-zero exit.
emulator
whitehall emulator [list | start <name> | create [name] | delete <name>] | Command | What it does |
|---|---|
emulator list | List available emulators. Alias ls |
emulator start <name> | Start one |
emulator create [name] | Create one. The name defaults to whitehall |
emulator delete <name> | Delete one, by ID or name. Aliases remove, rm |
Each takes --manifest, a path to whitehall.toml.
Passthroughs
The managed toolchain is not on your PATH, which is what keeps projects from
fighting over versions. These reach into it.
| Command | What it does |
|---|---|
adb … | Run adb from the managed SDK. It resolves the device too, so with two phones attached it asks or refuses by name rather than failing with adb's own more than one device/emulator |
fastboot … | Run fastboot from the managed SDK |
emu … | Run the emulator binary directly, e.g. whitehall emu -avd myavd |
avdmanager … | Run avdmanager |
exec <cmd> | Run one command inside the Android context: whitehall exec -- cargo test |
shell | Enter the Android context, a subshell where cargo run builds for the phone and runs there |
which <cmd> | Where a command resolves in the toolchain environment. Alias for exec which |
whitehall adb logcat
whitehall exec java -version
whitehall which gradle
whitehall shell shell and exec work in any directory; a whitehall.toml only pins the versions. Outside the shell nothing has changed.
whitehall adb rather than a system adb. It is the one from the
SDK this project builds against, so it cannot disagree with the APK you just installed.override
whitehall override set android writes .cargo/config.toml with the
target, the NDK linker and the runner, so a checked-in project builds for the phone without
anyone entering the shell, the way rustup override does. override
unset removes it.