DEV Community

Guilherme Rocha
Guilherme Rocha

Posted on

How to compile Rust command line tools for Termux

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

Let's add our compilation targets for rust using the rustup command:

rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

it's going to generate a single binary on $HOME/Android/binaries/bin, let's cd into there:

cd $HOME/Android/binaries/bin
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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

Top comments (1)

Collapse
 
inacio0196 profile image
Rafael Inácio

I was really looking for this, thanks a lot boy