lindroids: the CLI and, as lindroids server, a Wayland
compositor and PulseAudio-protocol sound server that also serves the page that draws its windows.
You can build it, test it and run your build on a phone with Rust alone: no Java, no Android
SDK, no NDK. Those are needed only for the few files listed under
Files that need other tools, and their outputs are committed.
Questions: Discord or an issue.
The code
Read docs/ARCHITECTURE.md first, then docs/DISPLAY.md
for the page and the link’s security, or docs/APPS.md for exported apps.
Build and test on a Linux PC
Rust stable from rustup.clang is optional: without it the build leaves
out two small preload libraries (the GTK 3 file picker and an x86 alarm() fix) and says so.
target/debug/lindroids run foot starts the server and
opens the page in your browser (xdg-open). LINDROIDS_LOG=debug logs more; the server’s log is
server.log in its runtime directory (lindroids status shows it). More, including
lindroids debug-app for scripted input: docs/TESTING.md.
Test a dev build
scripts/build.sh is for development only: it builds your checkout into a lindroids
package that installs over the release, so you can try a change before it is released. Everyone
else installs Lindroids with install.sh (README). scripts/use-release.sh goes back to an
official release. Both have --help.
build.sh finds the package manager of the system it runs in (or takes --format deb|pacman|rpm|apk), checks for everything the build needs and offers to install what is
missing with that package manager: Rust (rustup, or Termux’s rust), a C compiler, clang,
the Rust target, cargo-ndk and the Android NDK for phone builds on a PC, dpkg-deb, bsdtar,
adb. --yes installs it without asking; without a terminal it stops and prints the command.
The first build compiles every dependency (two minutes on a fast machine, longer on a phone;
about 1 GB with Rust), later ones only what changed. Clone the whole history (no --depth):
the version is counted from it.
A dev package is the release this commit would be, marked as a dev build: it installs over the
releases before it, and the release itself replaces it on a later upgrade.
A running server is kept until it is stopped:
--install stops an idle one, and one with
windows open says so. Run lindroids stop before trying a new build you installed another
way, or the old server keeps serving.
In Termux
lindroids stop, then ./target/release/lindroids run foot (the server is started from the binary that asked for it).
In a Linux distro: a container, a proot distro, a desktop
packaging/container.sh), so they build in proot
distros too. Void (xbps) has no dev packages. To make another system’s package,
--format and --target arm64|armhf|amd64|i386.
From a PC, for a phone
With the phone (or any Android device) in developer mode, USB debugging on, and plugged in:~/.local/share/lindroids-dev: no SDK, no Java; an NDK of yours is used if
ANDROID_NDK_HOME names it), adb and dpkg-deb from your package manager. On an immutable
system (Fedora Silverblue and the like) run it in a toolbox or distrobox. With several devices
attached, --device <serial> (from adb devices).
Then in Termux (after termux-setup-storage once, so it can read Download), the command it
printed:
--target aarch64|arm|x86_64|i686 builds a Termux package without a device. For a proot distro
on the phone, --target arm64 --format pacman --device --push (for example): proot-distro
shares the Download folder as /sdcard/Download. Packages go to target/dev-build/. Android 7
(API 24) is the oldest supported.
Back to a release
lindroids (apt, pacman, dnf, yum, zypper, apk or a static
install), downgrading from a dev build or a newer release as needed. The repositories keep the
newest three releases; older ones come from their GitHub release (a .deb checked against its
SHA256SUMS, an .rpm). pacman has only those three. Alpine’s repository is not published yet:
there the release’s static binary is put in /usr/local/bin instead.
What to try, and what to report
lindroids run foot(pkg install foot): a window, typing, the soft keyboard, closing it.lindroids export foot, then the app’s icon with Termux closed.- A GTK program (
pkg install mousepad), a Flatpak, or an X11 program (lindroids setup x11) if your change touches them. lindroids doctorwhen something does not start; the server’s log isserver.login the directorylindroids statusshows.
lindroids version, the device and
Android version, which Termux (F-Droid, GitHub or Google Play) or which distro, and the browser
if a window opened in one.
Files that need other tools
These are built rarely and committed, so nobody else needs the tools:The docs site
The Markdown indocs/ is also the docs site, published by Mintlify on
every push to main: docs.json (at the root) is its navigation, .mintignore keeps everything
else out. So a page reads well both on GitHub and on the site:
- each page starts with frontmatter (
title,description) instead of a#heading; - placeholders in prose go in backticks (
`<name>`): a bare<name>is read as a tag; - links to source files are full GitHub URLs; links between pages stay relative.
Pull requests
- Branch from
main; one change per pull request. - CI runs on every pull request:
cargo test --workspace,tests/host-integration.sh, shellcheck on the scripts, the window app build, and every package installed byinstall.shin containers of a dozen distros. Run the first two yourself before pushing, andtests/install-repos.sh(podman or docker) when you changepackaging/orinstall.sh. - Change the docs with the code: a new command in the README’s usage, a design decision in
docs/, with what was tried and what was found. - Commit messages say what changed for the user, in a short sentence (see
git log). - Every merge to
mainis a release (0.1.<commit count>), published to the package repositories, somainmust always work. - Contributions are licensed MIT OR Apache-2.0, as the project is.