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
Inside Ubuntu:
apt update && apt install build-essential git cmake ninja-build python3 g++ gcc libc6-dev
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
Note: LLVM_ENABLE_TERMINFO=OFF
avoids ncurses dependencies.
Compiling
ninja
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
Still, Clang and LLD are usable. Proceed with:
ninja install
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++
This is expected.
5. Solution: Manual Linking
#include <iostream>
int main() {
std::cout << "Hello from static LLVM binary!" << std::endl;
return 0;
}
Compile to object:
clang++ -c test.cpp -o test.o
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
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!
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)