I've been building a program to track how I spend my time, and a couple of the requirements are an interface on my phone, and sync between multiple devices. Since I haven't built an android app in forever, I decided to target termux, at least initially. This will allow me to use the app and test out the synchronization protocol without a ton of upfront effort into building a graphical user interface.

Cross Compiling for termux

The first thing we need to cross compile to termux is a cross compiler. rustc is a cross compiler by default, but with some important caveats: rustc needs a linker and a pre-made rust stdlib for the target platform.

I use the wonderful NixOS as my dev environment, so we will be using nix-shell to get the dependencies we need. In your project's directory, create an android.nix file and put the following code inside it.

# android.nix let # Get the mozilla nixpkg overlay for a convient rust installation moz_overlay = import ( builtins . fetchTarball https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz ); native-pkgs = import <nixpkgs> { overlays = [ moz_overlay ]; }; pkgs = import <nixpkgs> { crossSystem = native-pkgs . lib . systems . examples . armv7a-android-prebuilt ; }; # Get the latest stable compiler version and install the armv7 android target with it rust = ( native-pkgs . rustChannels . stable . rust . override { targets = [ " armv7-linux-androideabi " ]; }); in # Note the call to `pkgs` here, instead of `native-pkgs` pkgs . callPackage ( { mkShell, cargo } : # mkShell will drop us into a shell that has a $CC for the target platform mkShell { nativeBuildInputs = [ rust ]; } ) {}

Running nix-shell android.nix will drop you into a shell with cargo and an armv7 c compiler. Before we can build the rust project, we have to inform cargo to use said compiler for linking armv7 executables. Open .cargo/config (in your project's directory) and put the following in:

[target.armv7-linux-androideabi] linker = " armv7a-unknown-linux-androideabi-clang "

Now we can build our project termux! We simply start nix-shell and then tell cargo to compile the project:

$ nix-shell android.nix --run " cargo build --target=armv7-linux-androideabi "

Now just push the executable to your android device.

$ adb push target/armv7-linux-androideabi/debug/cli /storage/self/primary/our-cli-app

And then run the app from termux.

$ cp /storage/self/primary/our-cli-app ./ $ chmod ./our-cli-app $ ./our-cli-app --help

Results

It works! :O

Resources