There is currently no packaged end-user Navi install (.deb / Flatpak) for
Linux. What does exist is a desktop map shell (navi-desktop) plus the
Rust core, navi-linux gpsd/IMU demo, and WASM plugins. The richest
Automotive UX remains the Android host (app/); the Linux shell is the
developer / bring-up map UI.
Navi’s navigation logic lives in Rust (driver-break-core). On Linux you compile
that core (and plugins) with Cargo, and optionally run navi-desktop for a
real MapLibre map with route planning and live position.
Android APK / UniFFI: android-build.md.
Debugging loops: debugging.md.
Plugin build details: plugins.md.
Map styles / offline PMTiles: map-styles.md.
gpsd / IMU on Linux: see Sensors below and
imu-plugin.md.
ADB / device install from Linux: Android Debug Bridge (adb).
macOS host: build-macos.md.
Windows host: build-windows.md.
You need Git. On Debian, Ubuntu, and Mint:
sudo apt update
sudo apt install gitOther systems:
| System | Install Git |
|---|---|
| Fedora / RHEL / CentOS Stream | sudo dnf install git |
| Arch / Manjaro | sudo pacman -S git |
| openSUSE | sudo zypper install git |
| macOS | Xcode Command Line Tools (xcode-select --install) or brew install git — see build-macos.md |
| Windows | Git for Windows — see build-windows.md |
Then clone and switch to the development branch:
git clone https://github.com/Supermagnum/Navi.git
cd Navi
git checkout devOr clone dev in one step:
git clone -b dev https://github.com/Supermagnum/Navi.git
cd NaviIf you already cloned the repo, pull the latest commits on your current branch:
cd Navi
git checkout dev # if you are not already on dev
git pull origin devgit pull fetches from the remote and merges into your local branch. If you have
local uncommitted changes that conflict, either commit or stash them first
(git stash, then git pull, then git stash pop).
Branch / tag: Development happens on dev — that is where the newest
features are. main is the GitHub default (a plain git clone checks it
out). Use main only when you explicitly want that tip. There is no formal
release or stable-tag process yet. If tags appear later, prefer a documented
release tag for a frozen checkout.
If you do not already have a Rust toolchain:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shFollow the installer prompts, then reload your shell (or source "$HOME/.cargo/env").
Confirm:
rustc --version
cargo --versionDistro packages of Rust exist, but rustup is recommended so you can add
Android and WASM targets cleanly (see android-build.md and
below).
Toolchain pin: Workspace rust-version / rust-toolchain.toml channel is
1.98. That pin is for build reproducibility (CI and local rustup install
the exact channel). It is not a formally verified minimum: there is no CI
matrix job building an older claimed MSRV. Raised from 1.88 because wasmtime 48
(plugin-host) requires Rust >= 1.95. Do not lower the pin without proving the
dependency set still compiles; do not claim “MSRV verified” without adding that
matrix.
Guest plugins compile to wasm32-unknown-unknown (not WASI — guests get no
WASI filesystem or network; see plugins.md). Add the target
before building example plugins or running host isolation tests that compile
them:
rustup target add wasm32-unknown-unknownNative bits in the dependency tree need a C toolchain and often pkg-config.
Debian / Ubuntu:
sudo apt update
sudo apt install build-essential pkg-configFedora:
sudo dnf groupinstall "Development Tools"
sudo dnf install pkgconf-pkg-configArch Linux:
sudo pacman -S --needed base-devel pkgconfThe desktop shell embeds MapLibre GL JS via WebKitGTK (wry on Linux).
Install the development package so cargo build -p navi-desktop can link:
Debian / Ubuntu:
sudo apt install libwebkit2gtk-4.1-devFedora:
sudo dnf install webkit2gtk4.1-develArch Linux:
sudo pacman -S webkit2gtk-4.1Without those headers you can still build with
cargo build -p navi-desktop --no-default-features --features gpsd,linux-imu
and open the UI in a normal browser (--no-webview / --browser).
adb is not required for navi-desktop or Cargo core tests. Install it
when you talk to a phone/tablet/emulator from this Linux host — install APKs,
adb devices, adb logcat, push fixtures, or run Gradle
:app:installDebug. Full Android/NDK build steps:
android-build.md.
Option A — distro package (fastest for adb alone)
Debian / Ubuntu:
sudo apt update
sudo apt install adb android-sdk-platform-tools-common(android-sdk-platform-tools-common ships udev rules so USB devices show up
without running adb as root.)
Fedora:
sudo dnf install android-toolsArch Linux:
sudo pacman -S --needed android-toolsConfirm:
adb version
adb devicesOption B — Google platform-tools (matches Android Studio / SDK)
If you already use the Android SDK (needed to build the APK anyway):
# Typical SDK location after Android Studio or cmdline-tools:
export ANDROID_HOME="${ANDROID_HOME:-$HOME/Android/Sdk}"
export PATH="$ANDROID_HOME/platform-tools:$PATH"Install or refresh platform-tools with sdkmanager (or Android Studio →
SDK Manager → SDK Tools → Android SDK Platform-Tools):
# Example with cmdline-tools already under $ANDROID_HOME:
yes | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" "platform-tools"Or download the standalone zip from
Google’s platform-tools page,
unpack it, and put that platform-tools/ directory on your PATH.
USB device access
- On the Android device, enable Developer options (hidden by default):
- Open Settings → About phone (or About tablet / About device).
- Find Build number (sometimes under Software information).
- Tap Build number seven times until the device reports that you are a developer (you may need to unlock with PIN/pattern).
- Go back to Settings → System → Developer options (on some Samsung devices: Settings → Developer options).
- In Developer options, turn on USB debugging.
Optionally also enable Wireless debugging (Android 11+) if you will use
adbover Wi‑Fi. - Plug in USB; unlock the device and accept the Allow USB debugging? RSA fingerprint prompt (check Always allow from this computer if you trust this host).
- On Linux, if
adb devicesshowsunauthorizedor an empty list while the cable is connected, install the udev package above (Debian/Ubuntu) or copy rules from android-udev-rules, then replug and runadb kill-server && adb start-server && adb devices.
Expect a line like <serial> device (not offline / unauthorized).
Wireless debugging (optional)
On Android 11+ you can pair over Wi‑Fi (Developer options → Wireless
debugging) and use adb pair <ip>:<port> then adb connect <ip>:<port>.
Prefer USB for first-time installs and large adb push transfers.
| Library | Required? | Notes |
|---|---|---|
| SQLite | No system package required | Workspace uses rusqlite with the bundled feature |
| OpenSSL | Usually not | reqwest uses rustls-tls |
| GDAL / GEOS | Not used | Elevation via SRTM/Copernicus readers + geotiff, not GDAL |
| libgps | Not used | Optional gpsd client is pure Rust (gpsd_proto over TCP/JSON) |
| WebKitGTK 4.1 | For embedded desktop window | See above; runtime + -dev for the default embedded-webview feature |
SVG rasterization (usvg / resvg) and flate2 / png are pure Rust crates —
no extra system SVG libraries.
Full shared recipe: android-build.md. On Linux, from the
repository root after SDK/NDK/adb are set up (Prerequisites
and adb above):
export ANDROID_HOME="${ANDROID_HOME:-$HOME/Android/Sdk}"
export ANDROID_NDK_HOME="${ANDROID_NDK_HOME:-$ANDROID_HOME/ndk/<version>}"
export PATH="$ANDROID_HOME/platform-tools:$PATH"
# Physical arm64 tablet / phone
rustup target add aarch64-linux-android # once
./scripts/build-android-native.sh aarch64-linux-android release
./gradlew :app:assembleDebug
./gradlew :app:installDebug
adb shell am start -n no.navi.app/.MainActivityEmulator (x86_64 image):
rustup target add x86_64-linux-android # once
./scripts/build-android-native.sh x86_64-linux-android release
./gradlew :app:installDebug
./scripts/launch-navi-emulator.shConfirm the APK embeds libnavi.so for the ABI you built:
unzip -l app/build/outputs/apk/debug/app-debug.apk | grep 'lib/.*/libnavi.so'Manual install (same as Gradle :app:installDebug):
adb install -r app/build/outputs/apk/debug/app-debug.apk
adb shell am start -n no.navi.app/.MainActivity| Crate | Role on Linux |
|---|---|
core (driver-break-core) |
Elevation, routing, POI, rest/safety, search, icons, tracks, sensors |
navi-ffi |
UniFFI CDYLIB — Android ABI; also linked by navi-desktop for plan/search helpers |
navi-desktop |
Desktop map shell (WebKitGTK + MapLibre GL JS) |
plugin-host / plugin-sdk / plugins/* |
WASM sandbox; build/test on Linux |
navi-linux |
gpsd + IMU console demo (no map UI) |
Two paths were considered:
| Option | Stack | Result |
|---|---|---|
| A | eframe/egui + maplibre-rs |
Rejected for this pass. Upstream still describes itself as a proof-of-concept (crates.io ~0.0.3); missing labels/symbols/raster; no clear Protomaps PMTiles offline path matching Navi’s existing Android basemap work. |
| B (chosen) | WebKitGTK (wry/tao) + MapLibre GL JS + local axum HTTP |
Selected. Same MapLibre / OpenFreeMap / Protomaps ecosystem as Android; mature PMTiles protocol in JS; thin Rust server serves range requests against local .pmtiles and calls driver-break-core / navi-ffi for routing, search, and icons. Tradeoff: C WebKit dependency (documented above). |
Basemap resolution order mirrors Android BasemapStyleResolver: completed local
Protomaps PMTiles covering the camera when available, otherwise OpenFreeMap
Liberty online (--force-online forces Liberty). 3D / Mapterhorn hillshade
is out of scope for this shell. See map-styles.md.
Sensors reuse the same SensorBus path as navi-linux (gpsd + optional
--demo-imu). Routing uses plan_car_route from navi-ffi; icons use core
usvg/resvg rasterization.
# After WebKitGTK -dev is installed:
cargo run -p navi-desktop -- --demo-imu
# Or open the system browser instead of the embedded window:
cargo run -p navi-desktop -- --demo-imu --no-webviewUseful flags:
| Flag | Purpose |
|---|---|
--data-dir DIR |
Config / caches (default ~/.local/share/navi or $NAVI_DATA_DIR) |
--pbf PATH |
OSM extract for planning (defaults to Ostlandet under data-dir or core/target/integration-fixtures/) |
--pmtiles PATH |
Force offline Protomaps basemap |
--force-online |
Always use OpenFreeMap Liberty |
--place-index PATH |
FTS5 DB for place search |
--gpsd HOST:PORT |
gpsd address (default 127.0.0.1:2947) |
--demo-imu |
Synthetic IMU without hardware |
--listen HOST:PORT |
Bind for the local HTTP UI (default 127.0.0.1:0) |
--no-webview / --browser |
Use xdg-open instead of embedded WebKit |
Example with fixtures already on disk (see fixtures and map-styles.md):
cargo run -p navi-desktop -- --demo-imu --no-webview \
--pbf core/target/integration-fixtures/oppland-latest.osm.pbf \
--pmtiles core/target/integration-fixtures/europe_norway_ostlandet.pmtiles \
--elev-dir core/target/integration-fixtures/elevationEnter start/end as lat,lon (or use place search when --place-index is set).
First graph build from a large PBF is slow — prefer a regional extract when
possible.
Packaging (.deb / Flatpak) is out of scope for this pass — cargo run is
enough.
From the repository root (after Getting the code):
cd /path/to/Navi # e.g. ~/Navi after git clone
cargo build -p driver-break-core --releaseDebug build:
cargo build -p driver-break-coreOptional features (see core/Cargo.toml):
| Feature | Purpose |
|---|---|
gpsd |
Enable gpsd_proto client helpers in sensors |
linux-imu |
Enable Linux IMU fusion helpers (board-dependent) |
cargo build -p driver-break-core --features gpsd,linux-imuRequires wasm32-unknown-unknown (see Prerequisites):
cargo build --release --target wasm32-unknown-unknown \
--manifest-path plugins/log-hello/Cargo.tomlMore detail: plugins.md.
Unit / module tests (no large downloads):
cargo test -p driver-break-core
cargo test -p driver-break-core poi::
cargo test -p driver-break-core config::eco -- --nocapture
cargo test -p driver-break-core truck_multi_day -- --nocapture
cargo test -p driver-break-core motor_multi_day -- --nocapture
cargo test -p driver-break-core rest_area -- --nocapture
cargo test -p driver-break-core lodging -- --nocapture
cargo test -p driver-break-core --test truck_driving_history -- --nocaptureSeveral --ignored tests live under core/tests/ and write under
core/target/integration-fixtures/. On first run they download OSM extracts
(and DEM tiles where needed) over the network, then reuse the cache.
| Fixture | Source (approx. size) |
|---|---|
ostlandet-latest.osm.pbf |
Geofabrik (~430–450 MB) |
hedmark-latest.osm.pbf |
OSM.fr (~90 MB) |
oppland-latest.osm.pbf |
OSM.fr (~90 MB) |
DEM under integration-fixtures/elevation/ |
Downloaded by the test via core elevation jobs (corridor order ~100–200 MB once cached) |
europe_norway_ostlandet.pmtiles |
Regional Protomaps extract (~180 MB) — for navi-desktop offline basemap; see map-styles.md |
Disk space: Plan on about 1 GB free for a first pass of the common
ignored routing/hiking tests (OSM extracts + DEM). The fixtures directory can
grow to several GB if you also keep optional artefacts there (e.g. full
region PMTiles / DEM PMTiles from map tooling — not required for these Cargo
tests). See also test-results.md for recent PASS timings.
You do not need to download fixtures by hand for
kongsvinger_lillehammer_integration / dnt_hiking_integration: those tests
call download_if_missing themselves. Manual prefetch (optional):
mkdir -p core/target/integration-fixtures
curl -L -o core/target/integration-fixtures/ostlandet-latest.osm.pbf \
https://download.geofabrik.de/europe/norway/ostlandet-latest.osm.pbf
# hedmark / oppland URLs as in the table above, same directorySome other ignored tests only assert that ostlandet-latest.osm.pbf (or a
smaller corridor cut) already exists — place it under
core/target/integration-fixtures/ as above, or see comments in the specific
core/tests/*.rs file. Android corridor helpers:
android-test-results.md and
scripts/prepare-android-fixtures.sh.
cargo test -p driver-break-core --test kongsvinger_lillehammer_integration \
-- --nocapture --ignored
cargo test -p driver-break-core --test dnt_hiking_integration \
-- --nocapture --ignoredPlugin isolation (builds example guests for wasm32-unknown-unknown as needed):
cargo test -p navi-plugin-host --test isolation -- --nocaptureArchitecture (architecture.md): GPS/IMU belong on the highest-priority
sensor tier — publish-only, non-blocking.
| Source | Role |
|---|---|
| gpsd | Position, speed, course via TCP JSON (?WATCH=…); crate gpsd_proto (chosen over gpsd_client: same TCP/JSON, no libgps, explicit handshake/get_data API) |
| IMU | Heading / attitude for Compass and Direction-of-travel map modes; separate from gpsd |
Debian / Ubuntu:
sudo apt install gpsd gpsd-clientsFedora:
sudo dnf install gpsd gpsd-clientsArch Linux:
sudo pacman -S gpsd(gpsd-clients provides helpers such as cgps / gpspipe on Debian-family
distros; package names vary slightly.)
Typical USB GNSS dongle or serial adapter (device node may differ — check
dmesg / ls /dev/ttyUSB* / ls /dev/ttyACM*):
# Example: USB serial GNSS on /dev/ttyUSB0
sudo gpsd -N -n /dev/ttyUSB0Or, if your distro ships a systemd unit and device autodetection is configured:
sudo systemctl enable --now gpsdEdit distro gpsd defaults (e.g. /etc/default/gpsd on Debian) so DEVICES
lists your port when using the service. Default TCP port for clients:
127.0.0.1:2947.
# JSON stream: a few TPV/SKY sentences then exit
gpspipe -w -n 5
# Interactive curses client (wait for a fix)
cgps -sYou want a listening gpsd and, outdoors or with a simulator, a valid fix in
TPV. Handshake used by Navi (via gpsd_proto::ENABLE_WATCH_CMD):
?WATCH={"enable":true,"json":true};
Parse TPV (lat/lon/alt/speed/track) and optionally SKY (satellites / fix
quality). Feed samples into sensors::PositionSample / SensorBus.
navi-linux and navi-desktop enable gpsd + linux-imu by default. For
bring-up without an IMU chip, use --demo-imu: it publishes a rotating
synthetic heading on SensorBus.
# Console sensor demo
cargo run -p navi-linux -- --demo-imu
# Map shell with synthetic IMU
cargo run -p navi-desktop -- --demo-imu --no-webviewWithout a receiver, start gpsd only when you have a device (or a gpsd-compatible
simulator such as gpsfake); otherwise the gpsd thread may exit with an error
while --demo-imu continues to publish IMU samples. That is the intended
no-hardware on-ramp for the IMU side.
IMU is not provided by gpsd. On a Linux SBC with a real chip, use a board IMU
(e.g. BMI160 / BNO055 over I²C/USB) plus software fusion (linux-imu feature’s
simple filter, or uf-ahrs / chip fusion in deployment). Compass /
Direction-of-travel HUD modes on Android were proven with fed headings; on
Linux they should consume real gpsd course and/or IMU heading through the
same rotation-mode wiring (SensorBus → host map bearing).
Vehicle mounting pitch/roll zeroing for eco elevation correction is a deferred
feature — see imu-plugin.md.
With a live gpsd and optional --demo-imu, navi-linux prints POS (course) and
IMU (heading) lines — the same bus navi-desktop polls for the position marker.
| Feature | Status |
|---|---|
| MapLibre map + route planning shell | navi-desktop (this doc) — not pixel-parity with Android HUD |
| UniFFI Kotlin bindings / Gradle APK | Android NDK build (android-build.md) |
Android LocationManager / Automotive sensors |
Android only (Linux uses gpsd / IMU) |
| Compose HUD / approach-box animations / 3D terrain | Android only for now |
| Full Automotive UX parity | Use Android emulator or device |
Installable Linux package (.deb / Flatpak) |
Not yet — cargo run -p navi-desktop |
Linux is the right place for core algorithms, the desktop map shell, integrations, gpsd/IMU bring-up, and WASM plugins alongside Automotive UI work.
| Symptom | Likely fix |
|---|---|
linker / cc not found, or error: linker \cc` not found` |
Install the C toolchain (System packages: build-essential / base-devel / Development Tools). |
navi-desktop fails to find webkit2gtk-4.1 |
sudo apt install libwebkit2gtk-4.1-dev (or distro equivalent), or build with --no-default-features --features gpsd,linux-imu and --no-webview. |
| Plugin or isolation test fails to compile for WASM | rustup target add wasm32-unknown-unknown (guests are not wasm32-wasi). See plugins.md. |
navi-linux / desktop: gpsd loop ends / no POS |
Install and start gpsd; verify with gpspipe -w -n 5. Use --demo-imu for IMU without a chip. |
| Ignored integration test fails on missing PBF / HTTP error | Need network on first run, or prefetch extracts into core/target/integration-fixtures/ (fixtures). Ensure ~1 GB free disk. |
First api/plan is very slow |
Cold graph build from a large PBF; prefer a regional extract (e.g. Oppland) or wait for cache under --cache-dir. |
Odd compile errors after pulling dev or main |
cargo clean then rebuild; ensure rustup stable is current (rustup update). Do not hand-edit Cargo.lock unless resolving a deliberate pin — prefer cargo update / a clean tree from dev. |
pkg-config errors from a transitive crate |
Install pkg-config / pkgconf for your distro (see Prerequisites). |
adb: command not found |
Install adb (Android Debug Bridge): distro adb / android-tools, or $ANDROID_HOME/platform-tools on PATH. |
adb devices empty / unauthorized |
Enable Developer options (tap Build number seven times under About phone/tablet), turn on USB debugging, accept the RSA prompt; install udev rules (android-sdk-platform-tools-common or equivalent); adb kill-server && adb start-server. |