How to compile Rust command line tools for Termux
Guilherme Rocha
Posted on January 16, 2022
In this tutorial I gonna show you how you could compile and run Rust programs directly on your Android device with pretty much the same experience you would have on your Linux machine. But first, let's go to the basics.
What is Rust
Rust is a compiled system's programming language focused on safety and performance, being used by the Linux Kernel, Google, Microsoft and others for building embedded systems, webassembly tools and (you guessed) command line apps.
What is Termux
Termux is a terminal emulator for accessing your Android OS, since Android is UNIX-like, most of the commands you gonna be working with are basically the same on any Linux Distribution like Ubuntu or Debian, it also comes with it's own package manager called pkg. checkout the Wiki for more info on that.
Why you should read this tutorial?
If you are already aware of how Termux works or want to learn how to directly compile Rust for different architectures, this tutorial is totally for you.
Nuff Talking
First you gonna need some things:
- Git
- Rust
- Curl
- Android NDK and SDK
- SCP
- Unzip
- Python
- Nano (any text editor of your preference)
Ok... so let's get the requirements, first run on your terminal (I assume you are using a Debian-based machine or WSL with either Ubuntu or Debian installed):
sudo apt update && sudo apt install -y nano git curl unzip python
Now let's install Rust, they provide us an easy way of installing using the following command (it is going to ask you some things but just go for the default option provided):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Now finally the Android Requirements, it's gonna be a litte harder but I'm gonna try to make it all in one command:
mkdir $HOME/Android && \
cd $HOME/Android && \
mkdir sdk && \
wget -O sdk-tools.zip https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip && \
unzip sdk-tools.zip && rm sdk-tools.zip && \
mv tools ./sdk/tools && \
cd ./sdk/tools/bin && yes | ./sdkmanager --licenses && \
./sdkmanager "build-tools;29.0.2" "patcher;v4" "platform-tools" "platforms;android-29" "sources;android-29" "ndk-bundle" && \
echo "export ANDROID_SDK=\$HOME/Android/sdk" >> $HOME/.bashrc && \
echo "export ANDROID_NDK=\$ANDROID_SDK/ndk-bundle" >> $HOME/.bashrc && \
echo "export PATH=\$PATH:\$ANDROID_SDK/platform-tools:\$ANDROID_SDK/tools/bin" >> $HOME/.bashrc && \
source $HOME/.bashrc && cd $HOME
BTW, I know it's a huge command, but it's is either that or have Android Studio installed (and maybe you don't really want that :P), but what is does is install Android SDK Tools, configure them and add them to your path so you can use them without having to specify the entire path.
Configuring the NDK
Now that you have Android NDK you have to configure the toolchain for Rust to use it, rust will compile againt the mobile architectures so we gonna need a toolchain for arm64, arm and x86. NDK provide us a python script for creating a toolchain, All we have to run is:
mdkdir $HOME/Android/toolchains && \
cd $HOME/Android/toolchains && \
$ANDROID_NDK/build/tools/make_standalone_toolchain.py --api 26 --arch arm64 --install-dir ./arm64 && \
$ANDROID_NDK/build/tools/make_standalone_toolchain.py --api 26 --arch arm --install-dir ./arm && \
$ANDROID_NDK/build/tools/make_standalone_toolchain.py --api 26 --arch x86 --install-dir ./x86
Ok, now we have to tell rust where to find our toolchain with a config file, it will tell cargo (Rust's package manager) where to look for when trying to compile for those architectures, so with nano $HOME/.cargo/config
paste the following content
[target.aarch64-linux-android]
ar = "$HOME/Android/toolchains/arm64/bin/aarch64-linux-android-ar"
linker = "$HOME/Android/toolchains/arm64/bin/aarch64-linux-android-clang"
[target.armv7-linux-androideabi]
ar = "$HOME/Android/toolchains/arm/bin/arm-linux-androideabi-ar"
linker = "$HOME/Android/toolchains/arm/bin/arm-linux-androideabi-clang"
[target.i686-linux-android]
ar = "$HOME/Android/toolchains/x86/bin/i686-linux-android-ar"
linker = "$HOME/Android/toolchains/x86/bin/i686-linux-android-clang"
Let's add our compilation targets for rust using the rustup
command:
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android
FINALLY we are ready!!!!
Compiling a command line tool
I'm not going to make a command line tool from scratch, I'm gonna use something someone already made and shared the source code on Github. Let's use for example Dust, as the description says: "Like du but more intuitive".
First clone the repo:
git clone https://github.com/bootandy/dust
cd dust
Before compiling the tool checkout your what's your Android Architecture, in my example I have an arm64 (aarch64) device, but you could have a different one, on Termux run uname -m
to get this information.
Build the project with
cargo build --target aarch64-linux-android --release
if you navigate into target/aarch64-linux-android/release
and run file ./dust
you probably gonna have something similar to this:
ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, with debug_info, not stripped
YOU DID IT !!! but... how do I use it on my android phone? And why can't I execute it on my Linux machine when I try to run ./dust
?
First the second question, what you compiled is a aarch64 binary which it's linker points to the Android linker path.
The way we gonna tranfer the content of your Linux machine all the way to termux is via the scp
command, in other words it's ssh but for copying files.
Instead of having all those files to send let's make rust build a single binary, so it's going to be easier to transfer, for that run the following command, navigate back to dust base directory and then:
cargo install --target aarch64-linux-android --path . --root $HOME/Android/binaries
it's going to generate a single binary on $HOME/Android/binaries/bin
, let's cd into there:
cd $HOME/Android/binaries/bin
Great!!! now all we have to do is move the file over the network to Termux and bob's your uncle.
Copying the file with SCP
on Termux
Before opening the app go to 'Settings > Apps > Termux > Permissions > Storage' and enable storage, now you can tranfer the file with any problems, but let's install some required tools
# This has to be executed on Termux, not on Linux
pkg update && pkg upgrade
pkg install net-tools openssh
That's all, now we need the required information for copying over the file:
- User -> running
whoami
on Termux - Local Network IP -> run
ifconfig
and find your wlan0 ip address - Download Path -> we don't have it, so let's create one
On Termux, run:
mkdir $HOME/binaries
echo "export PATH=\$PATH:\$HOME/binaries" >> $HOME/.bashrc
source $HOME/.bashrc
Now inside the binaries folder run pwd
and passwd
to setup a default password.
Finally run this command to start your local ssh server
sshd -p 2222 -d
on Linux
The only thing you have to run here is
scp -P 2222 $HOME/Android/binaries/bin/dust <TERMUX_USER>@<TERMUX_IP>:<TERMUX_BINARIES_PATH>
There you have it, if you now run dust
on Termux it's going to work just fine
Thanks for Reading!!
I really appreciate if you liked this tutorial, no need for share or anything just let me know if you liked it or how can I improve
Posted on January 16, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.