DEV Community

GnomeMan4201
GnomeMan4201

Posted on

A Deep Dive: Statically Compiling LLVM 13 on Android with Termux

Disclaimer: This is a technical write-up intended for experienced users. All actions were performed on a non-rooted Android device using Termux + Proot Ubuntu.

1. Environment: Preparing the Battlefield

Device: Motorola Edge 2025 (ARM64)

Packages:

pkg install proot-distro git cmake ninja clang python
proot-distro install ubuntu
proot-distro login ubuntu
Enter fullscreen mode Exit fullscreen mode

Inside Ubuntu:

apt update && apt install build-essential git cmake ninja-build python3 g++ gcc libc6-dev
Enter fullscreen mode Exit fullscreen mode

Understanding the Filesystem (SYSROOT)

Ubuntu inside proot lives at:

/data/data/com.termux/files/usr/var/lib/proot-distro/installed-rootfs/ubuntu


2. Cloning and Configuring LLVM

git clone https://github.com/llvm/llvm-project.git
cd llvm-project
git checkout llvmorg-13.0.0
mkdir build && cd build

cmake ../llvm \
  -G Ninja \
  -DCMAKE_BUILD_TYPE=Release \
  -DLLVM_ENABLE_PROJECTS='clang;lld' \
  -DLLVM_TARGETS_TO_BUILD='AArch64' \
  -DCMAKE_INSTALL_PREFIX=$HOME/.local/llvm13 \
  -DLLVM_ENABLE_TERMINFO=OFF
Enter fullscreen mode Exit fullscreen mode

Note: LLVM_ENABLE_TERMINFO=OFF avoids ncurses dependencies.

Compiling

ninja
Enter fullscreen mode Exit fullscreen mode

Expect non-fatal warnings.


3. Build Failure: sancov

sancov fails due to an explicit constructor error at 95%:

error: chosen constructor is explicit in copy-initialization
Enter fullscreen mode Exit fullscreen mode

Still, Clang and LLD are usable. Proceed with:

ninja install
Enter fullscreen mode Exit fullscreen mode

Ignore failure related to missing sancov binary.


4. Static Linking Problem

clang++ -static test.cpp fails with:

ld: error: cannot open crt1.o
ld: error: unable to find library -lstdc++
Enter fullscreen mode Exit fullscreen mode

This is expected.


5. Solution: Manual Linking

#include <iostream>
int main() {
  std::cout << "Hello from static LLVM binary!" << std::endl;
  return 0;
}
Enter fullscreen mode Exit fullscreen mode

Compile to object:

clang++ -c test.cpp -o test.o
Enter fullscreen mode Exit fullscreen mode

Manual static link:

export SYSROOT=/data/data/com.termux/files/usr/var/lib/proot-distro/installed-rootfs/ubuntu

clang++ test.o -o test_static \
  --sysroot=$SYSROOT -static \
  -L$SYSROOT/lib/aarch64-linux-gnu \
  -L$SYSROOT/lib/gcc/aarch64-linux-gnu/13 \
  $SYSROOT/lib/aarch64-linux-gnu/crt1.o \
  $SYSROOT/lib/aarch64-linux-gnu/crti.o \
  $SYSROOT/lib/gcc/aarch64-linux-gnu/13/crtbeginT.o \
  -lc -lm -lstdc++ \
  $SYSROOT/lib/gcc/aarch64-linux-gnu/13/libgcc.a \
  $SYSROOT/lib/gcc/aarch64-linux-gnu/13/crtend.o \
  $SYSROOT/lib/aarch64-linux-gnu/crtn.o
Enter fullscreen mode Exit fullscreen mode

Link order matters. Avoid duplicate CRT symbols.


6. Validation

file ./test_static
# Output: statically linked ELF aarch64 binary

qemu-aarch64 -L $SYSROOT ./test_static
# Output:
Hello from static LLVM binary!
Enter fullscreen mode Exit fullscreen mode

Why This Is Useful

  • You get full native clang++ on Android
  • Works completely offline, non-rooted, and portable
  • Enables compiling, testing, and bootstrapping real toolchains inside Termux
  • Crucial for research, malware analysis, exploit development, or Red Team tool building on mobile

Disclaimer:

This article is intended for educational and research purposes only. All techniques and methods described should only be used in environments where you have explicit, legal authorization.

Unauthorized access, testing, or exploitation of devices or systems is illegal and unethical.

By proceeding, you agree to comply with all applicable laws and regulations, and to use the information solely for lawful, responsible security research and defensive purposes.

Top comments (0)