[GUIDE] How to install a Toolchain for clang on phones without root access

30 min read Original article ↗
You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an alternative browser.

bnsmb

Recognized Contributor / XDA University Professor
For phones with root access and installed Magisk, a clang toolchain can be installed using Magisk Modules (see here for details)

For phones without root access this approach is not possible.

Instead, the Termux app can be used: Termux is a full featured Linux environment including the clang toolchain. But Termux is a closed environment -- as long as you stay in Termux it's okay. But it's difficult to use Termux executables or executables created with the clang compiler in Termux, outsite of the Termux environment (See here for details about using Termux)

Therefore, I created a tar archive with the clang19 toolchain and other required tools to compile binaries with clang version 19 on the phone:

clang19_toolchain-v1.5.0_release_21.09.2025_.tar.gz

The tar file contains a clang19 toolchain that must be installed in the directory /data/local/tmp/sysroot.

The toolchain contains :

clang 19.0 binaries and files
make
cmake
ninja
the autoconf tools, libtool, and m4
pkg-config, pkgconf
gnupatch
binutils (addr2line ar as c++filt elfedit gprof ld ld.bfd nm objcopy objdump ranlib readelf size strings strip)
bison
flex
perl
python
pip
meson
texinfo
tcl
gdb
rsync
wget
curl
sshd/ssh
git
man
bash
nano
vi
tmux
openvpn

and some other tools -- all configured for the target directory /data/local/tmp/sysroot.

Most of the binaries in the tar file are compiled as static binary or as dynamic binary that only require the standard libraries from the Android OS.

The necesssary files to compile executables and libraries using clang in Android from the Android NDK are also part of the tar file.
As of 21.09.2025 the files from the Android NDK versions r27b, r27c, r27d, and r28b are part of the tar file.

To install the clang19 toolchain, these steps must be carried out:

First copy the tar flle to the phone

Note:

All commands below should be done in an adb shell by the standard user for adb shells -- that is the user shell. No root access is required for the commands.

Unpack the tar file in the directory

/data/local/tmp

The toolchain is then installed in the directory

/data/local/tmp/sysroot

Notes:

The unpacked tar file occupies about 2.7 GB space.

The path /data/local/tmp/sysroot is hardcoded in some of the binaries (e.g. the config files are expected to be in the directory /data/local/tmp/sysroot/etc), therefore the executables from the tar file may not work as expected if the tar file is installed in another directory. And be aware that the tar file must be installed on a partition with a Linux filesystem (like ext3 or ext4) - the installation in a partition formatted with the fat or extfat filesystem does not work.

After unpacking the tar file, prepare the clang19 toolchain environment with this command:

/data/local/tmp/sysroot/create_clang_env.sh

The script create_clang_env.sh creates the necessary directories and files for the clang19 toolchain. The script also initializes the OpenSSH config files and creates the necessary ssh host keys to start the sshd on the phone.
The script only needs to be executed once (but it can be executed more than once without problems).
ASUS_I006D:/data/local/tmp/sysroot $ date
Sun Sep 21 11:45:02 CEST 2025
ASUS_I006D:/data/local/tmp/sysroot $

ASUS_I006D:/data/local/tmp/sysroot $ ./create_clang_env.sh

Initializing the clang environment in /data/local/tmp/sysroot ...

The user executing this script is "shell"; the current home directory is "/data/local/tmp/sysroot/home/shell" ...
The directory "/data/local/tmp/sysroot/home/shell" already exists

Processing the certificate files ...
Copying the certificates from  "/system/etc/security/cacerts" to "/data/local/tmp/sysroot/etc/security/cacerts" ...
Creating the file "/data/local/tmp/sysroot/etc/security/ca-certificates.crt" ...
.................................................................................................................................................
... done:

-rw-rw-rw- 1 shell shell 218118 2025-09-21 11:45 /data/local/tmp/sysroot/etc/security/ca-certificates.crt

Configuring the certificate bundle file "/data/local/tmp/sysroot/etc/security/ca-certificates.crt" for git ...
The certificate bundle file for git is "/data/local/tmp/sysroot/etc/security/ca-certificates.crt"
(Use "git config --global http.sslCAInfo <cert_bundle_file>" to change that)

Processing the tar files with the NDKs in the directory "/data/local/tmp/sysroot/usr/ndk/" ...
The tar files with NDKs found are:

-rw-rw-r-- 1 shell shell 58624967 2025-09-20 15:28 r27b.tar.gz
-rw-rw-r-- 1 shell shell 59746977 2025-09-20 15:28 r27c.tar.gz
-rw-rw-r-- 1 shell shell 59737567 2025-09-20 15:28 r27d.tar.gz
-rw-rw-r-- 1 shell shell 72213190 2025-09-20 15:28 r28b.tar.gz

Processing the tar file "r27b.tar.gz" ...
The tar file contains the NDK "r27b"
Unpacking the tar file "r27b.tar.gz" ...
 ... tar file "r27b.tar.gz" succesfully unpacked

Processing the tar file "r27c.tar.gz" ...
The tar file contains the NDK "r27c"
Unpacking the tar file "r27c.tar.gz" ...
 ... tar file "r27c.tar.gz" succesfully unpacked

Processing the tar file "r27d.tar.gz" ...
The tar file contains the NDK "r27d"
Unpacking the tar file "r27d.tar.gz" ...
 ... tar file "r27d.tar.gz" succesfully unpacked

Processing the tar file "r28b.tar.gz" ...
The tar file contains the NDK "r28b"
Unpacking the tar file "r28b.tar.gz" ...
 ... tar file "r28b.tar.gz" succesfully unpacked

OK, the directory with the default NDK "/data/local/tmp/sysroot/usr/ndk/r27d" exists

Uncompressing the compressed files in "/data/local/tmp/sysroot/usr/bin" ...
No compressed executables found  in "/data/local/tmp/sysroot/usr/bin"
Creating the config file for vim /data/local/tmp/sysroot/home/shell/.vimrc ...

Correcting the SELinux context for the directory "/data/local/tmp/sysroot/var/tmp" ...

Executing now "/data/local/tmp/sysroot/create_ssh_env.sh" ...


Initializing the ssh environment in /data/local/tmp/sysroot ...

OK; the user executing this script is "shell"
The directory "/data/local/tmp/sysroot/var" already exists
Creating the directory "/data/local/tmp/sysroot/var/mail" ...
Creating the directory "/data/local/tmp/sysroot/var/empty" ...
Creating the directory "/data/local/tmp/sysroot/var/run" ...
The directory "/data/local/tmp/sysroot/home" already exists
The directory "/data/local/tmp/sysroot/home" already exists
Creating the ssh host key "/data/local/tmp/sysroot/etc/ssh/ssh_host_ecdsa_key" ...
Generating public/private ecdsa key pair.
Your identification has been saved in /data/local/tmp/sysroot/etc/ssh/ssh_host_ecdsa_key
Your public key has been saved in /data/local/tmp/sysroot/etc/ssh/ssh_host_ecdsa_key.pub
The key fingerprint is:
SHA256:7fjYbwuFID2nhPwYdisEvkxgPt1zBdqfNCIrNaOGRdw shell@localhost
The key's randomart image is:
+---[ECDSA 256]---+
|  o.o.  ...      |
| o =.+E= .       |
|  o = / X +      |
|   * * # @ +     |
|  . * + S = .    |
|   . . . o .     |
|        . o      |
|         + ..    |
|        . ooo.   |
+----[SHA256]-----+
Creating the ssh host key "/data/local/tmp/sysroot/etc/ssh/ssh_host_ed25519_key" ...
Generating public/private ed25519 key pair.
Your identification has been saved in /data/local/tmp/sysroot/etc/ssh/ssh_host_ed25519_key
Your public key has been saved in /data/local/tmp/sysroot/etc/ssh/ssh_host_ed25519_key.pub
The key fingerprint is:
SHA256:qmXJTiooO65KJbXgzqoKDMVnU6vqL87tyjaIH+pmERo shell@localhost
The key's randomart image is:
+--[ED25519 256]--+
|      .          |
| .   . .         |
| .o.+ .          |
|Eooo.o           |
|o+.o.   S        |
|*.o. . o         |
|oB+   B          |
|XB=o B           |
|^OBB* .          |
+----[SHA256]-----+
Creating the ssh host key "/data/local/tmp/sysroot/etc/ssh/ssh_host_rsa_key" ...
Generating public/private rsa key pair.
Your identification has been saved in /data/local/tmp/sysroot/etc/ssh/ssh_host_rsa_key
Your public key has been saved in /data/local/tmp/sysroot/etc/ssh/ssh_host_rsa_key.pub
The key fingerprint is:
SHA256:CvZ03e7AjLm6kfvIusVFzRItw8BfxB3E5KSMI0Nzkww shell@localhost
The key's randomart image is:
+---[RSA 3072]----+
|     .E=+=.==.   |
|     ..o*B++o    |
|      o.=+= .    |
|       +.+ .     |
|    o . S . .    |
|   . = = = .     |
|      B o + .    |
|     o + . o     |
|    oo*+o   .    |
+----[SHA256]-----+
The file "/data/local/tmp/sysroot/etc/ssh/sshd_config" already exists
(The template for the file "/data/local/tmp/sysroot/etc/ssh/sshd_config" in this tar archive is "/data/local/tmp/sysroot/etc/ssh/sshd_config.new" )
The file "/data/local/tmp/sysroot/etc/ssh/ssh_config" already exists
(The template for the file "/data/local/tmp/sysroot/etc/ssh/ssh_config" in this tar archive is "/data/local/tmp/sysroot/etc/ssh/ssh_config.new" )
Creating the empty file "/data/local/tmp/sysroot/etc/ssh/authorized_keys" ...


To enable access via ssh add your public ssh key to the file

/data/local/tmp/sysroot/etc/ssh/authorized_keys

To start the sshd use the command

/data/local/tmp/sysroot/usr/sbin/sshd

The sshd then listens on the port 9022

To connect to the sshd on this machine use the command

ssh -p 9022 192.168.1.148

To copy a file via scp to this machine use the command

scp -P 9022 [source_file]  192.168.1.148:[targetfile|targetdir]

To connect to other machines using ssh from this phone use

/data/local/tmp/sysroot/usr/bin/ssh [hostname]

To make the ssh binaries available via PATH variable execute

source /data/local/tmp/sysroot/init_ssh_env



Use the command

source /data/local/tmp/sysroot/bin/init_clang19_env

to init the clang19 session in an adb shell



ASUS_I006D:/data/local/tmp/sysroot $

To use the clang19 toolchain, open an adb shell and source the script to init the environment:
source /data/local/tmp/sysroot/bin/init_clang19_env

or
. /data/local/tmp/sysroot/bin/init_clang19_env

init_clang19_env sets some environment variables and adds the directories with the compiler and tools to the variable PATH.

If root access is enabled on the phone, the script init_clang19_env also

  • enables Socket access for the user shell (this is necessary to run tmux as user shell)
  • enables creating hard links for the user shell
  • enables access to FIFOs for the user shell
Note:

These config changes are optional and not required to use the clang19 toolchain. The config changes are only temporay until the next reboot.

If the clang toolchain is installed in another directory this command can be used to initialize the clang toolchain:

CLANG_SYSROOT="<dir_with_the_clang19_toolchain>"  source ${CLANG_SYSROOT}/bin/init_clang19_env

Using this command, the script uses the correct directory in the environment variables. But be aware that the hardcoded directories in the libraries and executables are still using /data/local/tmp/sysroot.
ASUS_I006D:/data/local/tmp/sysroot $ date
Sun Sep 21 11:47:21 CEST 2025
ASUS_I006D:/data/local/tmp/sysroot $

ASUS_I006D:/data/local/tmp/sysroot $ source bin/init_clang19_env
The toolchain directory used is "/data/local/tmp/sysroot"
Checking if the current CPU can execute binaries for arm64 CPUs using the binary "/data/local/tmp/sysroot/bin/testcpu" ...
OK, the current CPU can execute executables for arm64 CPUs.
Running as user "shell"

Preparing the clang environment for creating binaries for the CPU type aarch64

Using clang 19                                                                        

Using the NDK /data/local/tmp/sysroot/usr/ndk/r27d                                         (environment variable NDK_DIR)
Using the sysroot directory /data/local/tmp/sysroot/usr/ndk/r27d/sysroot                   (environment variable SYSROOT)
Using the target root directory /data/local/tmp/develop/sysroot                            (environment variable TARGET_ROOT)


Environment variables used:

PATH is now:              /data/local/tmp/develop/sysroot/usr/bin:/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin:/data/local/tmp/sysroot/usr/bin:/data/local/tmp/sysroot/bin:/data/local/tmp/sysroot/usr/clang19/bin

LD_LIBRARY_PATH:          :/data/local/tmp/sysroot/usr/lib:/data/local/tmp/sysroot/usr/ndk/r27d/sysroot/usr/lib/aarch64-linux-android:/data/local/tmp/sysroot/usr/clang19/lib

API is now:               31
NDK_DIR is now:           /data/local/tmp/sysroot/usr/ndk/r27d

SYSROOT is now:           /data/local/tmp/sysroot/usr/ndk/r27d/sysroot

CFLAGS are now:            -I/data/local/tmp/sysroot/usr/include -I/data/local/tmp/sysroot/usr/clang19/include -I/data/local/tmp/sysroot/usr/ndk/r27d/include -I/data/local/tmp/sysroot/usr/ndk/r27d/sysroot/usr/include/aarch64-linux-android -I/data/local/tmp/sysroot/usr/ndk/r27d/sysroot/usr/include -I/data/local/tmp/develop/sysroot/usr/include --sysroot=/data/local/tmp/sysroot/usr/ndk/r27d/sysroot

CPPFLAGS are now:          -I/data/local/tmp/sysroot/usr/include -I/data/local/tmp/sysroot/usr/clang19/include -I/data/local/tmp/sysroot/usr/ndk/r27d/include -I/data/local/tmp/sysroot/usr/ndk/r27d/sysroot/usr/include/aarch64-linux-android -I/data/local/tmp/sysroot/usr/ndk/r27d/sysroot/usr/include -I/data/local/tmp/develop/sysroot/usr/include --sysroot=/data/local/tmp/sysroot/usr/ndk/r27d/sysroot

CXXFLAGS are now:          -I/data/local/tmp/sysroot/usr/include -I/data/local/tmp/sysroot/usr/clang19/include -I/data/local/tmp/sysroot/usr/ndk/r27d/include -I/data/local/tmp/sysroot/usr/ndk/r27d/sysroot/usr/include/aarch64-linux-android -I/data/local/tmp/sysroot/usr/ndk/r27d/sysroot/usr/include -I/data/local/tmp/develop/sysroot/usr/include --sysroot=/data/local/tmp/sysroot/usr/ndk/r27d/sysroot

LDFLAGS are now:           -L/data/local/tmp/sysroot/usr/lib -L/data/local/tmp/sysroot/usr/ndk/r27d/sysroot/usr/lib/aarch64-linux-android/31 -L/data/local/tmp/sysroot/usr/ndk/r27d/sysroot/usr/lib/aarch64-linux-android -L/data/local/tmp/develop/sysroot/usr/lib -B/data/local/tmp/sysroot/usr/ndk/r27d/sysroot/usr/lib/aarch64-linux-android/31/ --sysroot=/data/local/tmp/sysroot/usr/ndk/r27d/sysroot -lc

CC is now:                /data/local/tmp/sysroot/usr/clang19/bin/clang
CXX is now:               /data/local/tmp/sysroot/usr/clang19/bin/clang++
CPP is now:               /data/local/tmp/sysroot/usr/clang19/bin/clang-cpp
CXXCPP is now:            /data/local/tmp/sysroot/usr/clang19/bin/clang-cpp
AR is now:                /data/local/tmp/sysroot/usr/clang19/bin/llvm-ar
AS is now:                /data/local/tmp/sysroot/usr/clang19/bin/llvm-as
LD is now:                /data/local/tmp/sysroot/usr/clang19/bin/lld
RANLIB is now:            /data/local/tmp/sysroot/usr/clang19/bin/llvm-ranlib
STRIP is now:             /data/local/tmp/sysroot/usr/clang19/bin/llvm-strip
PKG_CONFIG is now:        /data/local/tmp/sysroot/usr/clang19/bin/pkg-config
PKG_CONFIG_PATH is now:   :/data/local/tmp/sysroot/usr/lib/pkgconfig/:/data/local/tmp/develop/sysroot/usr/lib/pkgconfig/

Checking the clang binary ...

clang version 19.0.0git (https://android.googlesource.com/toolchain/llvm-project b3a530ec6537146650e42be89f1089e9a3588460)
Target: aarch64-unknown-linux-android
Thread model: posix
InstalledDir: /data/local/tmp/sysroot/usr/clang19/bin

Define some aliase ...
sysroot='cd /data/local/tmp/sysroot; pwd'
setlibpath='export LD_LIBRARY_PATH=:/data/local/tmp/sysroot/usr/lib:/data/local/tmp/sysroot/usr/ndk/r27d/sysroot/usr/lib/aarch64-linux-android:/data/local/tmp/sysroot/usr/clang19/lib'
addlib='LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/data/local/tmp/develop/sysroot/usr/lib '
vi=/data/local/tmp/sysroot/usr/bin/vi
find=/data/local/tmp/sysroot/usr/bin/find
tar=/data/local/tmp/sysroot/usr/bin/tar
bash=/data/local/tmp/sysroot/usr/bin/bash
sed=/data/local/tmp/sysroot/usr/bin/sed
awk=/data/local/tmp/sysroot/usr/bin/awk
dd=/data/local/tmp/sysroot/usr/bin/dd
nano=/data/local/tmp/sysroot/usr/bin/nano
curl=/data/local/tmp/sysroot/usr/bin/curl

Root access is enabled on this machine

Enabling hard links for the user "shell" ...
Enabling creating and using fifos for the user "shell" ...

Setting the variable "SSL_CERT_FILE" to "/data/local/tmp/sysroot/etc/security/ca-certificates.crt" ...

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $

Now you can compile programs on the phone with clang or clang++ in an adb shell using the configure scripts from the source code of most Unix tools .

Note that init_clang19_env must be executed in every new adb session once before the toolchain can be used.

Use

sh /data/local/tmp/sysroot/bin/init_clang19_env help
to print the usage help for the script:
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $ date
Sun Sep 21 11:56:05 CEST 2025
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $ source bin/init_clang19_env help

Usage: . /data/local/tmp/sysroot/bin/init_clang19_env [-h|--help] [init] [var=value] [examples] [nocpucheck]
 
init        - clear the used enviroment variables at script start
var=value   - set the environment variable "var" to "value" at start of the script
examples    - print compile examples
nocpucheck  - disable the CPU check

Supported environment variables are:

  CHECK_CPU="${CHECK_CPU:=${__TRUE}}"
  TMPDIR="${TMPDIR:=/data/local/tmp}"
  CLANG_SYSROOT="${CLANG_SYSROOT:=/data/local/tmp/sysroot}"
  TARGET_ROOT="${TARGET_ROOT:=/data/local/tmp/develop/sysroot}"
  CLANG_VERSION="${CLANG_VERSION:=19}"
  CLANG_DIR="${CLANG_DIR:=${CLANG_SYSROOT}/usr/clang${CLANG_VERSION}}"
  NDK="${NDK:=r27d}"
  NDK_DIR="${NDK_DIR:=${CLANG_SYSROOT}/usr/ndk/${NDK}}"
  SYSROOT="${SYSROOT:=${NDK_DIR}/sysroot}"
  API=${API:=31}


To use another toolchain base directory use this syntax:

  CLANG_SYSROOT=/data/local/tmp/sysroot  source ${CLANG_SYSROOT}/bin/init_clang19_env

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $

The default API level configured in the init script is 31; this API version was introduced in Android 12 (-> the binaries created with this clang19 toolchain should work with Android 12 and newer versions)

(see https://source.android.com/docs/setup/reference/build-numbers for the list of supported API levels)

To use another API level use the syntax

source /data/local/tmp/sysroot/bin/init_clang19_env_help API=[API level]

Example:
source /data/local/tmp/sysroot/bin/init_clang19_env API=28

Note that some symbols that are standard in the libc of Linux are only defined in the libc of Android versions with newer API levels. To test in which libc version a symbol is defined, the executable nm can be used.

Example:

ASUS_I006D:/ # for i in   /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/*/libc.so ; do echo "*** $i: "; nm $i | grep __fpending ; done
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/21/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/22/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/23/libc.so:
00000000000140c8 T __fpending
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/24/libc.so:
00000000000150c8 T __fpending
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/25/libc.so:
00000000000150c8 T __fpending
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/26/libc.so:
00000000000160c8 T __fpending
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/27/libc.so:
00000000000160c8 T __fpending
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/28/libc.so:
00000000000180c8 T __fpending
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/29/libc.so:
00000000000180c8 T __fpending
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/30/libc.so:
000000000001a0c8 T __fpending
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/31/libc.so:
000000000001a0c8 T __fpending
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/32/libc.so:
000000000001a0c8 T __fpending
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/33/libc.so:
000000000001a0c8 T __fpending
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/34/libc.so:
000000000001a0c8 T __fpending
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/35/libc.so:
000000000001a0c8 T __fpending
ASUS_I006D:/ #

-> the symbol __fpending is defined in the libc from API version 23 and newer.
If you get an error like this trying to execute a binary on Android:
ASUS_I006D:/data/local/tmp/develop/done/cpython314 $ ./python
CANNOT LINK EXECUTABLE "./python": cannot locate symbol "close_range" referenced by "/data/local/tmp/develop/done/cpython314/python"...
1|ASUS_I006D:/data/local/tmp/develop/done/cpython314 $

check the libc.so from Android for the missing symbol "close_range":
ASUS_I006D:/data/local/tmp/sysroot/home/shell # for i in   /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/*/libc.so ; do echo "*** $i: "; nm $i | grep close_range ; done
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/21/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/22/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/23/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/24/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/25/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/26/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/27/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/28/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/29/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/30/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/31/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/32/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/33/libc.so:
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/34/libc.so:
000000000001cb50 T close_range
*** /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/35/libc.so:
000000000001cb50 T close_range
ASUS_I006D:/data/local/tmp/sysroot/home/shell #

-> API 34 is Android 14 so this binary does not work on Android 13 or older versions.

The important directories in the tar file are:
DirectoryContentComment
/data/local/tmp/sysroot/bina few binaries and symbolic links for the tools
/data/local/tmp/sysroot/usr/binbinaries for the tools
/data/local/tmp/sysroot/usr/liblibraries for the tools
/data/local/tmp/sysroot/usr/libexechelper files and binaries for the tools
/data/local/tmp/sysroot/etcconfig files for the tools
/data/local/tmp/sysroot/usr/include/some include files that might be used to compile the binaries
/data/local/tmp/sysroot/usr/sharedata files for the tools
/data/local/tmp/sysroot/usr/ndk/#ndkversion##ndkversion# is the NDK version; as of 19.05.2025 the NDK versions in the tar archive are r27b and r27c
/data/local/tmp/sysroot/usr/clang19/directory tree with the clang files
/data/local/tmp/sysroot/usr/clang19/bin/directory with the binaries for clang

It's recommended to create another directory structure for the compiled binaries and libraries, e.g. :

/data/local/tmp/develop/sysroot/usr/
/data/local/tmp/develop/sysroot/usr/bin
/data/local/tmp/develop/sysroot/usr/lib
/data/local/tmp/develop/sysroot/usr/include

The init script /data/local/tmp/sysroot/bin/init_clang19_env adds the directories in

/data/local/tmp/develop/sysroot/usr

to the variables CFLAGS and LDFLAGS if they exist (see the script file for details)

The tar file also contains some simple C, C++, and assembler programs to test the compiler. Use the parameter ex or example for the script init_clang19_env to print the instructions to compile these sample files e.g.:

ASUS_I006D:/ $ source /data/local/tmp/sysroot/bin/init_clang19_env ex
The toolchain directory used is "/data/local/tmp/sysroot"
Running as user "shell"

Preparing the clang environment for creating binaries for the CPU type aarch64

...

To test the clang environment use

cd /data/local/tmp/sysroot
clang ${CFLAGS} ${LDFLAGS} -o helloworld_in_c helloworld_in_c.c  && ./helloworld_in_c

To test the C++ compiler use

cd /data/local/tmp/sysroot
clang++ ${CPPFLAGS} ${LDFLAGS}  -o helloworld_in_c++ ./helloworld_in_c++.cpp && ./helloworld_in_c++

To test the assembler from CLANG use

cd /data/local/tmp/sysroot
clang -nostdlib -static -Wl,--entry=_start -o helloworld_in_assembler helloworld_in_assembler.s && ./helloworld_in_assembler

To test the assembler from the binutils use

cd /data/local/tmp/sysroot
/data/local/tmp/sysroot/usr/bin/as -o helloworld_in_assembler_for_as.o helloworld_in_assembler_for_as.s &&   /data/local/tmp/sysroot//usr/bin/ld -o helloworld_in_assembler_for_as helloworld_in_assembler_for_as.o &&   ./helloworld_in_assembler_for_as

[clang19 toolchain] ASUS_I006D:/ $
[clang19 toolchain] [shell@localhost /]$ cd /data/local/tmp/sysroot
[clang19 toolchain] [shell@localhost /data/local/tmp/sysroot]$
 
[clang19 toolchain] [shell@localhost /data/local/tmp/sysroot]$ clang ${CFLAGS} ${LDFLAGS} -o helloworld_in_c helloworld_in_c.c  && ./helloworld_in_c
Hello, World from a C program!
Compiled with Clang 19.0.0
[clang19 toolchain] [shell@localhost /data/local/tmp/sysroot]$
 
[clang19 toolchain] [shell@localhost /data/local/tmp/sysroot]$ clang++ ${CPPFLAGS} ${LDFLAGS}  -o helloworld_in_c++ ./helloworld_in_c++.cpp && ./helloworld_in_c++
Hello, World from a C++ program!
Compiled with Clang 19.0.0
Compiler version: Clang 19.0.0git (https://android.googlesource.com/toolchain/llvm-project b3a530ec6537146650e42be89f1089e9a3588460)
[clang19 toolchain] [shell@localhost /data/local/tmp/sysroot]$
 
[clang19 toolchain] [shell@localhost /data/local/tmp/sysroot]$ clang -nostdlib -static -Wl,--entry=_start -o helloworld_in_assembler helloworld_in_assembler.s && ./helloworld_in_assembler
Hello, World from an assembler program compiled with clang!
[clang19 toolchain] [shell@localhost /data/local/tmp/sysroot]$
 
[clang19 toolchain] [shell@localhost /data/local/tmp/sysroot]$ /data/local/tmp/sysroot/usr/bin/as -o helloworld_in_assembler_for_as.o helloworld_in_assembler_for_as.s &&   /data/local/tmp/sysroot//usr/bin/ld -o helloworld_in_assembler_for_as helloworld_in_assembler_for_as.o &&   ./helloworld_in_assembler_for_as
Hello, World from an assembler program compiled with as and ld from the binutils!
[clang19 toolchain] [shell@localhost /data/local/tmp/sysroot]$

Notes

The binaries in the toolchain are tested in Android 13, Android 14, Android 15, and (partially) Android 16; they should also work in Android 12..

As of 21.09.2025, the tar file contains these program versions:

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $ date
Sun Sep 21 11:49:19 CEST 2025
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $  grep "^#" README | cut -c2-
 The tools included in the tar file with the clang19 toolchain are:
 
 clang 19.0.0
 cmake 4.0.1
 ninja 1.12.1 and 1.13.1
 make 4.4.1
 meson 1.7
 binutils 2.44 (addr2line  ar  as  c++filt  elfedit  gprof  ld  ld.bfd  nm  objcopy  objdump  ranlib  readelf  size  strings  strip)
 
 autoconf 2.72
 automake 1.17
 m4 1.4.20
 libtool 2.5.3
 patch 2.8 (gnupatch)
 patchelf 0.18
 GNU help2man 1.49.3
 pkg-config 0.29
 pkgconf 2.30
 autopoint 0.23
 texinfo 7.2
 
 bash 5.2.37
 
 bison 3.8
 flex 2.6.4
 
 gdb 16.3 (dynamically and statically linked binaries)
 
 rsync 3.4.1
 
 wget 2.1.0
 curl 8.13.0
 
 perl 5.40
 python 3.14
 pip 25.0.1
 tcl 9.0
 sqlite3 3.50.1
 
 sshd/ssh 10.0p2
 
 git 2.49
 
 gpg 1.4.3
 
 dig 9.11.37
 
 nano 8.6 and nano 6.4
 vim 9.1-672
 ed 1.21
 bvi /bmore 1.5.0
 
 man 2.13
 
 tmux 3.5a
 
 tar 1.35
 dd 9.5.58
 
 jq 1.7.1
 
 gawk 5.3.2
 grep 3.12
 gsed 4.9
 diff 3.11
 bc 1.08.2
 less 679
 htop 3.4.1
 btop 1.4.4 (btop needs root access)
 
 Android SDK build tools 35.0.2 (aidl zipalign aapt aapt2 dexdump split-select e2fsdroid sqlite3 fastboot sload_f2fs hprof-conv etc1tool mke2fs make_f2fs adb make_f2fs_casefold veridex)
 ( the binaries are from this ZIP file: https://github.com/lzhiyong/android-sdk-tools/releases/download/35.0.2/android-sdk-tools-static-aarch64.zip )

 OpenVPN 2.7 (openvpn requires root access)

 unfsd 0.11.0 (a userland NFS daemon usable by non-root user; the default exports file for this binary is /data/local/tmp/sysroot/etc/exports)

 protoc v32.1.0 (currently the binary only)

 various compression tools:
 
 7zz 25.00
 bzip2 1.0.8
 zip 3.0
 unzip 5.52
 lz4 v1.10.0
 lzop 1.04
 compress 5.0
 uncompress 5.0
 zstd 1.5.6
 pigz 2.8
 xz 5.8.1
 gunzip 1.13
 gzip 1.13
 unrar 5.91
 lzip 1.25

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $

The include file sysroot/usr/include/add_missing_definitions.h contains dummy definitions for common functions and definitions from Linux that are not available in Android.
The file is also available here: add_missing_definitions.h

To use the file, add the statement

#include <add_missing_definitions.h>

to the source file.

As of 21.05.2025 the include files add these symbols:

// Please note that you must remove the definitions for functions that already exist in the source code from this include file.
// If not, error messages like this are displayed when compiling your source code:
//
//    command.c:(.text+0x348): multiple definition of `catclose'
//    array.o:array.c:(.text+0x348): first defined here
//
// Therefore, either edit this file before using it or copy only the necessary parts to your source files

// This file defines
//   __GNUC_PREREQ
//   quad_t
//   u_quad_t
//   short
//
// This file defines the functions
//   strverscmp
//   versionsort
//   getdtablesize
//   index
//   rindex
//   catopen
//   catgets
//   catclose
//   nl_langinfo
//   getpwent
//   endpwent
//   CloseSocket
//

The file is also available here: add_missing_definitions.h

The dummy library sysroot/usr/lib/libmylib.so can be used to create libraries that are needed in the Makefile of a tool but are not necessary in Android (like libpthread.so).
Simply create a symbolic link for the missing library to libmylib.so, e.g.

cd /datda/local/tmp/sysroot/usr/lib
ln -s ./libmylib.so ./libptrhead.so

The file is also available here: libmylib.so

wget2, curl, and git from the tar file use the certificates from the bundle file /data/local/tmp/sysroot/etc/security/ca-certificates.crt. This file is created by the script create_clang_env.sh with all certificates found in /system/etc/security/cacerts.

If git complains about an invalid SSL certificate, like this

ASUS_I006D:/data/local/tmp/develop/test $ git clone https://github.com/git/git
Cloning into 'git'...
fatal: unable to access 'https://github.com/git/git/': SSL peer certificate or SSH remote key was not OK
128|ASUS_I006D:/data/local/tmp/develop/test $
use the wrapper script

git_no_ssl_verify

(see https://git-scm.com/book/be/v2/Git-Internals-Environment-Variables for other environment variables used by git)

In case of an error when executing a self compiled binary, I recommend to create a binary with debug infos and execute the binary from within the GNU debugger gdb, which is part of the toolchain
(see https://www.sourceware.org/gdb/ for details about the GNU debugger)

To create a binary with debugging infos use the compiler switches "-g -O0" and do not use the linker switch "-s"

If there is no gzip on the phone to unpack the tar file, download the gzip binary from here.

The tar file contains also the OpenSSH binaries and scripts as described in this HowTo: How to connect to Android via ssh as user shell without root access

see these posts and HowTos for examples using the clang19 toolchain:

How to compile jq in Android using the clang19 toolchain

How to compile nano in Android with the clang19 toolchain on the phone

How to compile Perl in Android with the clang19 toolchain on the phone

How to compile bash in Android with the clang19 toolchain on the phone

How to compile Python in Android with the clang19 toolchain on the phone

see also Troubleshooting some common problems for compiling programs for Android for how to fix some common problems compiling binaries for Android


TroubleShooting

An error like this

[clang19 toolchain] [shell@localhost /]$ /data/local/tmp/sysroot/usr/clang19/bin/clang-19
CANNOT LINK EXECUTABLE "/data/local/tmp/sysroot/usr/clang19/bin/clang-19": cannot locate symbol "_ZTTNSt6__ndk114basic_ifstreamIcNS_11char_traitsIcEEEE" referenced by "/data/local/tmp/sysroot/usr/clang19/lib/libclang-cpp.so"...
[clang19 toolchain] [shell@localhost /]$

is caused by an incompatible libc++_shared.so on the phone, e.g.:
[clang19 toolchain] [shell@localhost /]$ ldd  /data/local/tmp/sysroot/usr/clang19/bin/clang-19 | grep libc++_shared.so
    libc++_shared.so => /system/lib64/libc++_shared.so (0x7bf528a000)
[clang19 toolchain] [shell@localhost /]$

To fix the error, change the LD_LIBRARY_PATH so that the libc++_shared.so is used by clang, e.g.:
[clang19 toolchain] TB351FU:/ $ ldd   /data/local/tmp/sysroot/usr/clang19/bin/clang-19 | grep libc++_shared.so                                        
   libc++_shared.so => /data/local/tmp/sysroot/usr/lib/libc++_shared.so (0x7a9b687000)
[clang19 toolchain] TB351FU:/ $


The toolchain can also be used in an ssh session to the phone (the sshd binary is part of the tar file with the toolchain).

The toolchain can also be used in adb sessions connected via WiFi -- see the section How to enable adb via WiFi with a fixed TCP port for instructions to enable adb via WiFi with a fixed TCP port.

see the post How to install clang20 on phones without root access for the documentation for an additional tar archive with clang20.

A git repository with libraries and include files that can be used to create executables with the clang19 toolchain in Android is available on github:

https://github.com/bnsmb/libraries-and-include-files-for-Android-on-arm64-CPUs/

To use the files from that repository with the clang19 toolchain, download the repository to the phone

cd /data/local/tmp/
git clone https://github.com/bnsmb/libraries-and-include-files-for-Android-on-arm64-CPUs.git

and move the sysroot directory from the repository to the directory /data/local/tmp/develop before initializing the clang19 toolchain.

Update 11.07.2025

See these posts for how to use overlay mounts to install a clang19 toolchain (Note: to use overlay mounts root access is required)

Using a virtual disk with a clang19 toolchain for an overlay mount

Using a virtual disk with Perl 5.42 and a minimal clang19 toolchain for an overlay mount

Update 22.10.2025

see Using a virtual disk with a clang21 toolchain and Android NDK r29 for an overlay mount for the documentation for a virtual disk with clang21 and the Android NDK r29 (Note: the approach used in this guide needs root acces)

23.01.2025

added links to examples for using the clang19 toolchain

25.01.2025

added the info about the git repository with libraries and include files for Android

24.03.2025

updated the docoumentation to match the release v1.2.0 23.03.2025

21.05.2025

updated the docoumentation to match the release v1.3.0 21.05.2025

11.07.2025

added the links to the post with infos about using overlay mounts

21.07.2025

updated the docoumentation to match the release v1.4.0 21.07.2025

21.09.2025

updated the docoumentation to match the release v1.5.0 21.09.2025

28.10.2025

Updated the link to the instructions to compile Perl using the clang19 toolchain
added the Trouble Shooting section

bnsmb

Recognized Contributor / XDA University Professor

bnsmb

Recognized Contributor / XDA University Professor
Update

I released the new version of the clang19 toolchain today:

clang19_toolchain-v1.1.0_release_25.01.2025_.tar.gz

Changes in this version are:

  25.01.2025 v1.1.0 /bs
    updated rsync to version 3.4.1
    added man pages for rsync
    updated git to version 2.48
    added man pages for git
    added gpg 1.4.23
    added pkgconf 2.30
    added a wrapper for clang : /data/local/tmp/sysroot/usr/bin/cc
    added a wrapper for cpp : /data/local/tmp/sysroot/usr/bin/cpp
    the script init_clang19_env now adds the directory /data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/include/aarch64-linux-android to the include dirs in CFLAGS
    replaced the perl executables in the archive with perl executables compiled on the phone using clang19 and API version 31
    installed and configured CPAN
    added tar 1.34
    added jq 1.7.1
    added the dummy library sysroot/usr/lib/libmylib.so
    added an include file with dummys for functions missing in Android: sysroot/usr/include/add_missing_definitions.h
    updated nano to version 8.3
    the executable xz now works without the library liblzma.so.5
    added the SELinux tools (libsepol-3.7)

The description in the 1st post of this thread has been adapted to the new version

One updated script in the clang19 toolchain can also be useful for others:

The script myldd is a wrapper for the awfull ldd script from Android; the usage is:

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $ myldd
Usage /data/local/tmp/sysroot/usr/bin/myldd [binary] [...]
[clang19 toolchain] 1|ASUS_I006D:/data/local/tmp/sysroot $

Usage examples
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot/usr/bin $ ls -l ifstat
-rwxr-xr-x 1 shell shell 27296 2025-01-25 19:14 ifstat
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot/usr/bin $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot/usr/bin $ myldd ifstat

# Executing ldd "/data/local/tmp/sysroot/usr/bin/ifstat"
    linux-vdso.so.1 => [vdso] (0x706c08c000)
    libm.so => /apex/com.android.runtime/lib64/bionic/libm.so (0x706ad80000)
    libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x706ac93000)
    libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x706ac60000)
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot/usr/bin $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot/usr/bin $ ls sh
ls: sh: No such file or directory
[clang19 toolchain] 1|ASUS_I006D:/data/local/tmp/sysroot/usr/bin $

[clang19 toolchain] 1|ASUS_I006D:/data/local/tmp/sysroot/usr/bin $ myldd sh

# Executing ldd "/system/bin/sh"
    linux-vdso.so.1 => [vdso] (0x7bf9081000)
    libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x7bf7c91000)
    libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x7bf7c7b000)
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot/usr/bin $



[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot/usr $ ls bin/mksh
bin/mksh
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot/usr $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot/usr $ myldd bin/mksh                                                                                                                                                                      
# Executing ldd "/data/local/tmp/sysroot/usr/bin/mksh"
    linux-vdso.so.1 => [vdso] (0x7d9ccc6000)
    libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x7d9b99f000)
    libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x7d9b88c000)
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot/usr $

The script myldd is also available here: myldd
Last edited:
Is there any way to install clang 15 on termux? I need it because I'm compiling something which has implicit function definitions, which were deprecated in clang 16 and later.

bnsmb

Recognized Contributor / XDA University Professor
There is no clang15 in the Termux repositories . So, if you need clang15 in Termux downloaded the sources and compile it yourself

bnsmb

Recognized Contributor / XDA University Professor
Update

I have released the new version of the clang19 toolchain:

clang19_toolchain-v1.2.0_release_23.03.2025_.tar.gz

Changes in this version are:

 23.03.2025 v1.2.0 /bs
    added nmon 16q
    added scoat 1.8.0.2
    added gawk 5.1.0
    added gsed 4.8
    added diff 3.8
    added dd 9.5.58
    the script create_patch_script.sh now uses the command "patch -p1 <patch>" to apply the patches
    added the wrapper script /data/local/tmp/sysroot/bin/myconfigure (this script executes the script myconfigure in the current directory)
    added autopoint from gettext 0.23
    added patchelf 0.18
    updated the OpenSSH binaries to version 9.9p2
    updated git to version 2.49

The description in the 1st post of this thread has been adapted to the new version

bnsmb

Recognized Contributor / XDA University Professor
Minor Update

The flex binary in the clang19 toolchain (/data/local/tmp/sysroot/usr/bin/flex) sometimes crashes with a segmentation fault. This should be fixed in the current executable for flex in the github repository for the clang19 toolchain. To download the flex binary from the github repository use this link:

https://raw.githubusercontent.com/b..._android/refs/heads/main/sysroot/usr/bin/flex

I've added the NDK r27c to the github repository for the clang19 toolchain. To download only the r27c NDK use this link:

https://github.com/bnsmb/clang19_to...w/refs/heads/main/sysroot/usr/ndk/r27c.tar.gz

To install the NDK r27c copy the file r27c.tar.gz into the directory

/data/local/tmp/sysroot/usr/ndk

and execute in an adb shell

cd /data/local/tmp/sysroot/usr/ndk && gzip -cd r27c.tar.gz | tar -xf -

To use the NDK r27c either change the value of the variable

NDK_DIR

in the file

/data/local/tmp/sysroot/bin/init_clang19_env

to

/data/local/tmp/sysroot/usr/ndk/r27c

or use this command to initialize the clang19 toolchain environment

 NDK_DIR=/data/local/tmp/sysroot/usr/ndk/r27c source /data/local/tmp/sysroot/bin/init_clang19_env

(r27c is the current LTS version of the NDK)

Note that I did not create a new release of the clang19 toolchain for these minor changes

bnsmb

Recognized Contributor / XDA University Professor
Update 23.04.2025

A tar file with the clang 20 that can be installed as add-on to the tar file with the clang 19 is described in this post

bnsmb

Recognized Contributor / XDA University Professor
Update

I have released the new version of the clang19 toolchain:

clang19_toolchain-v1.3.0_release_21.05.2025_.tar.gz

or from the github repository:

https://github.com/bnsmb/clang19_toolchain_for_android/releases/tag/v1.3.0_21.05.2025

Changes in this version are:

  21.05.2025 v1.3.0 /bs
    the script /data/local/tmp/create_clang_env.sh now supports multiple NDKs
    removed the file LLVMPolly.so from the archive with NDK r27b files -- this is a library for x86
    added the files from the NDK r27c
    the flex binary in the toolchain failed sometimes with a segmentation fault -- fixed
    added the header files for the ncurses libraries
    minor changes to the scripts create_clang_env.sh and bin/init_clang19_env (see the history section in these files)
    added textinfo 7.2
    added ed 1.21
    updated diff to version 3.11
    added pip 25.0.1
    added meson 1.7
    recompiled python3 with clang19; all default python modules except _posixshmem, _tkinter, and _dbm are part of the python installation
    pkg-config 0.29 now only requires the standard Android OS libraries
    the script bin/init_clang19_env now exports the environment variable DEFAULT_SSL_CERT_FILE if the file /data/local/tmp/sysroot/etc/security/ca-certificates.crt exists
    the script bin/init_clang19_env now exports the environment variable PKG_CONFIG_PATH
    the script create_clang_env.sh used a wrong value for HOME and therefore some configuration files were created in the wrong directories -- fixed
    updated bash to version 5.2.37
    replaced m4 with a new compiled binary to avoid core dumps
    added bc 1.08.1
    updated xz to version 5.8.1
    updated gawk to version 5.3.2; gawk is now a dynamically bind executable
    updated nano to version 8.4
    updated less to version 668
    updated curl to version 8.13.0
    moved the autoconf directories and files to sysroot/usr/<subdir>
    use symbolic links for clang clang++ clang-cl clang-cpp
    use symbolic links for ld64.lld ld.lld  lld-link
    use symbolic links for llvm-addr2line llvm-bitcode-strip llvm-dlltool llvm-install-name-tool llvm-lib llvm-otool llvm-ranlib llvm-readelf llvm-strip llvm-windres wasm-ld
    updated cmake to version 4.0.1 (the binaries for cmake are now stripped and not compressed anymore)
    added ninja 1.12.1
    updated OpoenSSH to version 10.0p2 using the libraries from OpenSSL 3.5
    updated OpenSSL to version 3.5
    updated the binutils to version 2.44 (addr2line  ar  as  c++filt  elfedit  gprof  ld  ld.bfd  nm  objcopy  objdump  ranlib  readelf  size  strings  strip)
    added grep 3.12 (the name used for the binary is ggrep)
    added example programs for the CLANG assembler and the assembler from the binutils
    nmon now only needs the standard Android OS libraries

There are now also two simple Hello World programs to test the Assembler in the tar archive; the commands to compile these assembler source files are:
[clang19 toolchain] [shell@localhost /data/local/tmp/sysroot]$ clang -nostdlib -static -Wl,--entry=_start -o helloworld_in_assembler helloworld_in_assembler.s && ./helloworld_in_assembler
Hello, World from an assembler program compiled with clang!
[clang19 toolchain] [shell@localhost /data/local/tmp/sysroot]$


[clang19 toolchain] [shell@localhost /data/local/tmp/sysroot]$ /data/local/tmp/sysroot/usr/bin/as -o helloworld_in_assembler_for_as.o helloworld_in_assembler_for_as.s &&   /data/local/tmp/sysroot//usr/bin/ld -o helloworld_in_assembler_for_as helloworld_in_assembler_for_as.o &&   ./helloworld_in_assembler_for_as
Hello, World from an assembler program compiled with as and ld from the binutils!
[clang19 toolchain] [shell@localhost /data/local/tmp/sysroot]$

The tar file contains the necessary files from multiple NDKs. The default NDK used is still r27b.
To use another NDK version either edit the file init_clang19_env or set the variable NDK before executing init_clang19_env,

Example:

NDK=r27c source /data/local/tmp/sysroot/bin/init_clang19_env

The init_clang19_env script, which initiates the clang19 toolchain environment, now supports installation in a directory other than /data/local/tmp/sysroot:

If the clang19 toolchain is installed in another directory this command can be used to initialize the environment::

CLANG_SYSROOT="<dir_with_the_clang19_toolchain>"  source ${CLANG_SYSROOT}/bin/init_clang19_env

Using this command, the script uses the correct directory in the environment variables. But be aware that the hardcoded directories in the libraries and executables are still using /data/local/tmp/sysroot.

The description in the 1st post of this thread has been adapted to the new version

bnsmb

Recognized Contributor / XDA University Professor
Update

I have released the new version of the clang19 toolchain:

clang19_toolchain-v1.4.0_release_21.07.2025_.tar.gz

or from the github repository:

https://github.com/bnsmb/clang19_toolchain_for_android/releases/tag/v1.4.0_21.07.2025

Changes in this version are:

 21.07.2025 v1.4.0 /bs
    updated gdb to version 16.3 
    removed the directories arm-linux-androideabi  i686-linux-android  riscv64-linux-android  x86_64-linux-android from the directory sysroot/usr/lib in the NDK r27c
    added the alias cp_crt_libs to copy the crt*.o files to the current directory
    added the Android NDK r28b
    updated sqlite3 to version 3.50.1
    init_clang19_env now uses the executable sysroot/bin/testcpu to check if the current CPU can execute binaries compiled for arm64 CPUs
    tests like "[ -x /system/bin/sh ]" now work in the bash from this archive 
    added the Android SDK build tools 35.0.2
    added the binaries pstree, killall, and fuser from https://github.com/acg/psmisc
    updated lmm to verson 2.1.2
    updated ack to version 3.9.0
    the privilege separation user in OpenSSH is now "nobody" and the sshd can be started by the root user
    recompiled the bison binary with the correct prefix /data/local/tmp/sysroot/usr
    the flex binary now uses the m4 in /data/local/tmp/sysroot/usr/bin/
    the default config file for rsyncd is now /data/local/tmp/sysroot/etc/rsyncd.conf
    ncat recompiled with prefix=/data/local/tmp/sysroot/
    ncat.static recompiled with prefix=/data/local/tmp/sysroot/
    added the alias make_fast (= make -j$( nproc ) )
    updated htop to version 3.4.1
    added OpenVPN 2.7
    updated 7zz to version 25.00
    added pigz 2.8
    updated nano to version 8.5
    added lzip 1.25
    updated list_bind_mounts.sh to version 1.3.0
    updated ninja to version 1.13.1
    updated less to version 679
    updated bc to version 1.08.2 ; added dc
    updated sed (gsed) to version 4.9
    updated gnupatch to version 2.8
    updated tar to version 1.35

The tar file contains the necessary files from multiple NDKs. The default NDK used is still r27b.

To use another NDK version either edit the file init_clang19_env or set the variable NDK before executing init_clang19_env,

Example:

NDK=r27c source /data/local/tmp/sysroot/bin/init_clang19_env

The description in the 1st post of this thread has been adapted to the new version

bnsmb

Recognized Contributor / XDA University Professor
Update

I have released the new version of the clang19 toolchain:

clang19_toolchain-v1.5.0_release_21.09.2025_.tar.gz

or from the github repository:

https://github.com/bnsmb/clang19_toolchain_for_android/releases/tag/v1.5.0_21.09.2025

This is only a minor update with some updated tools and some minor fixes .

Changes in this version are:

  21.09.2025 v1.5.0 /bs
    added the files from the Android NDK r27d
    the default Android NDK version used is now r27d
    updated vim to version 9.1 with patches 1-1629
    updated curl to version 8.15.0
    added btop 1.4.4 (btop needs root access)
    updated nano to version 8.6
    updated m4 to version 1.4.20
    bison binary recompiled with these configure options "--prefix=/data/local/tmp/sysroot/usr  --datarootdir=/data/local/tmp/sysroot/usr/share --datadir=/data/local/tmp/sysroot/usr/share "
    added unfsd 0.11.0 
    added a a statically linked sqlite3 binary (sqlite3.static)
    added the binary protoc v32.1.0
    recreated the tar file with the files from the NDK r27d to remove the leading "./" from the path names in the tar file
    updated bvi and bmore to version 1.5.0
    added statically linked gdb binaries
    removed the dependency on libc++_shared.so from some binaries
    corrected the broken symlink for ninja
    nmap, nping, ncat now use config files in  /data/local/tmp/sysroot/etc/ (except /etc/ethers)
    deleted not working binary bin/soelim (there is still a soelim in usr/bin)

The tar file contains the necessary files from multiple NDKs. The default NDK used is now r27d.

To use another NDK version either edit the file init_clang19_env or set the variable NDK before executing init_clang19_env,

Example:

NDK=r27c source /data/local/tmp/sysroot/bin/init_clang19_env

The description in the 1st post of this thread has been adapted to the new version

bnsmb

Recognized Contributor / XDA University Professor
A tar file with the files from the Android NDK r29 for use with the clang19 toolchain is now available here:

r29.tar.gz

The tar file with the files is also available in the GitHub repository with the clang19 toolchain:

https://github.com/bnsmb/clang19_to...aw/refs/heads/main/sysroot/usr/ndk/r29.tar.gz

Usage:

Download the tar file to the phone

/data/local/tmp/sysroot/usr/bin/wget http://bnsmb.de/files/public/Android/tar_files/r29.tar.gz
and extract the tar file in the directory /data/local/tmp/sysroot/usr/ndk

To use the Android NDK r29, init the clang19 environment then with this command:

source /data/local/tmp/sysroot/bin/init_clang19_env NDK=r29
or
NDK=r29 source /data/local/tmp/sysroot/bin/init_clang19_env

To always use the Android NDK r29 change the default value for the variable NDK in the script /data/local/tmp/sysroot/bin/init_clang19_env

Change this line:

[clang19 toolchain] ASUS_I006D:/ $ grep NDK= /data/local/tmp/sysroot/bin/init_clang19_env                                                                                        
  NDK="${NDK:=r27d}"
[clang19 toolchain] ASUS_I006D:/ $

Notes

The ChangeLog for the Android NDK r29 is here:

https://github.com/android/ndk/wiki/Changelog-r29

bnsmb

Recognized Contributor / XDA University Professor
A tar file with the files from the Android NDK r29 for use with the clang19 toolchain is now available here:

r29.tar.gz

Usage:

Download the tar file to the phone

/data/local/tmp/sysroot/usr/bin/wget http://bnsmb.de/files/public/Android/tar_files/r29.tar.gz
and extract the tar file in the directory /data/local/tmp/sysroot/usr/ndk

To use the Android NDK r29, init the clang19 environment then with this command:

source /data/local/tmp/sysroot/bin/init_clang19_env NDK=r29
or
NDK=r29 source /data/local/tmp/sysroot/bin/init_clang19_env

To always use the Android NDK r29 change the default value for the variable NDK in the script /data/local/tmp/sysroot/bin/init_clang19_env

Change this line:

[clang19 toolchain] ASUS_I006D:/ $ grep NDK= /data/local/tmp/sysroot/bin/init_clang19_env                                                                                        
  NDK="${NDK:=r27d}"
[clang19 toolchain] ASUS_I006D:/ $

Notes

The ChangeLog for the Android NDK r29 is here:

https://github.com/android/ndk/wiki/Changelog-r29

Similar threads