Hints and Examples for compiling Unix programs for Android

 Last Update: 06.06.2026/bs

(see also the News section)


Contents

 
  1. Hints and Examples for compiling Unix programs for Android
    1. Contents
    2. Introduction
    3. News
    4. History
    5. Overview
    6. How to setup the various tool chains
      1. How to compile a C program for Android using gcc from the Android NDK
      2. How to compile a C program for Android using the clang from the Android NDK
      3. How to compile a C program for Android using a recent GCC cross-compiler
      4. How to compile a C program for Android in Android using clang
        1. How to install clang on the phone
        2. How to install a toolchain for clang19 on phones without root access
        3. How to install clang20 on phones without root access
      5. How to compile a C program for Android in Android using gcc
        1. How to compile a C or C++ program for Android in Android with gcc without root access
        2. How to compile a C program for Android in Android using a Magisk module with gcc
      6. How to compile a C program for Android in Android in Termux
    7. General hints
      1. How to create dynamically linked binaries for Android using C or C++
    8. Examples for compiling programs on the PC using the Android NDK
      1. Examples for compiling programs using the gcc from the Android NDK
        1. How to compile pigz using the gcc from the Android NDK
        2. How to compile the ncurses library using the gcc from the Android NDK
        3. How to compile bvi using the gcc from the Android NDK
        4. How to compile nmon using the gcc from the Android NDK
        5. How to compile less using the gcc from the Android NDK
        6. How to compile vim using the gcc from the Android NDK
        7. How to compile Perl 5.40 using the gcc from the Android NDK
        8. How to compile OpenSSL using the gcc from the Android NDK
      2. Examples for compiling programs using the clang from the Android NDK
        1. How to compile pigz using the clang from the Android NDK
        2. How to compile the ncurses library using the clang from the Android NDK
        3. How to compile bvi using the clang from the Android NDK
        4. How to compile cpio using clang from the Android NDK
        5. How to compile bc using clang from the Android NDK
        6. How to compile libnl3 using clang from the Android NDK
        7. How to compile libpcap using clang from the Android NDK
        8. How to compile ngrep using clang from the Android NDK
        9. How to compile a static linked bvi using clang from the Android NDK
        10. How to compile NcFTP using clang from the Android NDK
      3. Examples for compiling programs using a recent GCC cross-compiler
        1. How to compile pigz using a recent GCC cross-compiler
        2. How to compile the ncurses library using a recent GCC cross-compiler
        3. How to compile bvi using a recent GCC cross-compiler
    9. Examples for compiling programs on the phone running Android
      1. Examples for compiling programs in Termux
        1. How to compile pigz for Android in Termux
        2. How to compile the ncurses library for Android in Termux
        3. How to compile bvi for Android in Termux
        4. How to compile Perl for Android in Termux
      2. Examples for compiling programs using the gcc toolchain in Android
        1. How to compile pigz in Android using the gcc toolchain on the phone
        2. How to compile the ncurses library in Android using the gcc toolchain on the phone
        3. How to compile bvi in Android using the gcc toolchain on the phone
        4. How to compile python3 in Android using the gcc toolchain
      3. Examples for compiling programs using the new gcc toolchain in Android
        1. How to compile pigz in Android using the new gcc toolchain on the phone
        2. How to compile the ncurses library in Android using the new gcc toolchain on the phone
        3. How to compile bvi in Android using the new gcc toolchain on the phone
      4. Examples for compiling programs using the clang toolchain in Android
        1. How to compile pigz in Android using the clang19 toolchain on the phone
        2. How to compile the ncurses library in Android using the clang19 toolchain on the phone
        3. How to compile bvi in Android using the clang19 toolchain on the phone
        4. How to compile Perl in Android using the clang19 toolchain on the phone
        5. How to compile jq in Android using the clang19 toolchain on the phone
        6. How to compile nano in Android using the clang19 toolchain on the phone
        7. How to compile bash in Android using the clang19 toolchain on the phone
        8. How to compile Python in Android using the clang19 toolchain on the phone
        9. How to compile OpenSSL in Android using the clang19 toolchain on the phone
        10. How to compile jsoncpp in Android using the clang19 toolchain on the phone (using cmake)
        11. How to compile curl in Android using the clang19 toolchain on the phone (using cmake and ninja)
        12. How to compile bzip2 in Android using the clang19 toolchain on the phone (using meson and ninja)
    10. Using the Android source code tree to compile binaries for Android
      1. How to compile only a single binary file from Android
      2. How to build a program from Android (such as dmctl) as a statically linked binary
    11. Links
      1. Useful Android apps and tools
   

Introduction



On this page you can find guides for compiling Unix C or C++ programs for Android.

Please note that all instructions for the PC in the HowTos apply to the Linux OS.

If you encounter an error while compiling a Unix program for Android, I recommend checking this page for a solution: Common problems when compiling a C/C++ source file for Android and how to fix them



Compiled binaries for Android on arm64 CPUs can be found here:

http://bnsmb.de/files/public/Android/binaries_for_arm64/
 
and in this GitHub repository:

https://github.com/bnsmb/binaries-for-Android


Magisk modules with compiled binaries for Android can be found here:

http://bnsmb.de/Magisk_Modules.html


My web page with general hints and guides for Android is available here: My Howtos for Android 



News


News

none


Old news
none





Back to my home page


History

 
ChangeLog


06.06.2026

updated the section How to create dynamically linked binaries for Android using C++ or C (see also here)


03.06.2026

updated the section How to compile a C or C++ program for Android in Android with gcc without root access (see also here)        


01.06.2026

updated the section How to compile a C or C++ program for Android in Android with gcc without root access (see also here)        
added the section How to compile a C program for Android using a recent GCC cross-compiler  
added the section Examples for compiling programs using a recent GCC cross-compiler  
added the section How to compile pigz using a recent GCC cross-compiler  
added the section How to compile the ncurses library using a recent GCC cross-compiler  
added the section How to compile bvi using a recent GCC cross-compiler 



31.05.2026

added the section How to compile a C or C++ program for Android in Android with gcc without root access 
renamed the section with the info about install the Magisk module with gcc to How to compile a C program for Android in Android using a Magisk module with gcc       
added the section Examples for compiling programs using the new gcc toolchain in Android   
added the section How to compile pigz in Android using the new gcc toolchain on the phone  
added the section How to compile the ncurses library in Android using the new gcc toolchain on the phone  
added the section How to compile bvi in Android using the new gcc toolchain on the phone  



26.05.2026

added the section How to build a program from Android (such as dmctl) as a statically linked binary   
updated the section How to compile only a single binary file from Android (see also here)     


24.05.2026

added the section How to compile dmctl  


19.04.2026 /bs

initial release

  
 


Overview


There are various methods to compile a C or C++ Unix program for Android:

You can compile a C/C++ program

This page contains general guides for using all of these methods and also example instructions for compiling some tools with these tool chains.


I have created instructions for compiling pigz, the ncurses library, and the bvi binary for each of the tool chains so that you can compare the effort required to compile a Unix program using one of the tool chains.


In case of an error when compiling a C program, it's recommended to check the page

Common problems when compiling a C/C++ source file for Android and how to fix them

for hints to fix common compile errors. This page also contains some general guidelines and hints for compiling Unix programs for Android. I therefore recommend that you read this page before compiling a Unix program for Android.


I recommend using a virtual machine to compile C programs for Android if using the Android NDK to avoid accidentally destroying your running Linux operating system.


My personal favorite environment for compiling C/C++ programs is the clang19 toolchain on Android. This toolchain contains most of the tools required to compile existing C/C++ Unix programs for Android (clang, make, cmake ninja, meson, autoconf tools, m4, pkg-config, bison, flex, perl, python, gdb, patch, git, wget, curl etc). The clang19 toolchain does not need root access. And in my experience, this toolchain produces the fewest errors (disclaimer: I'm the author of the clang19 toolchain ...)



How to setup the various tool chains



How to compile a C program for Android using gcc from the Android NDK



How to compile a C program for Android using gcc from the Android NDK


Android is in the end just another Linux and therefore many C programs that were developed for Linux can also be compiled to run in the Android OS.
 
The tool chain required to compile a C program for Android is part of the Android NDK; the Android NDK can be downloaded from here: https://developer.android.com/ndk/downloads 

The current version of the Android NDK only contains the compiler clang. In principle clang should be able to compile all C programs, but some make files for existing C programs require the compiler gcc.

The gcc compiler was part of the Android NDK in some of the earlier versions of the NDK. Therefor to compile a C program with the compiler gcc one of the earlier versions of the Android NDK must be used.

Old Android NDK versions are available here: https://github.com/android/ndk/wiki/Unsupported-Downloads

Android NDKs are available as tar file -- to install the Android NDK just download the tar file with the Android NDK and untar it.


The example below is for the Android NDK version r14b "installed"in the directory /data/develop/android/android-ndk-r14b on a machine running the Linux OS.
(NDK=/data/develop/android/android-ndk-r14b)


The Android NDK version r14b contains an initial root directory with the include files and libraries most frequently used by Linux programs for various SDK versions in the directory

${NDK}/platforms

e.g.

ls -l platforms
xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$ ls -l platforms
total 45
drwxr-xr-x 5 xtrnaw7 xtrnaw7      5 Mar 15  2017 android-12
drwxr-xr-x 5 xtrnaw7 xtrnaw7      5 Mar 15  2017 android-13
drwxr-xr-x 5 xtrnaw7 xtrnaw7      5 Mar 15  2017 android-14
drwxr-xr-x 5 xtrnaw7 xtrnaw7      5 Mar 15  2017 android-15
drwxr-xr-x 5 xtrnaw7 xtrnaw7      5 Mar 15  2017 android-16
drwxr-xr-x 5 xtrnaw7 xtrnaw7      5 Mar 15  2017 android-17
drwxr-xr-x 5 xtrnaw7 xtrnaw7      5 Mar 15  2017 android-18
drwxr-xr-x 5 xtrnaw7 xtrnaw7      5 Mar 15  2017 android-19
drwxr-xr-x 8 xtrnaw7 xtrnaw7      8 Mar 15  2017 android-21
drwxr-xr-x 8 xtrnaw7 xtrnaw7      8 Mar 15  2017 android-22
drwxr-xr-x 8 xtrnaw7 xtrnaw7      8 Mar 15  2017 android-23
drwxr-xr-x 8 xtrnaw7 xtrnaw7      8 Mar 15  2017 android-24
drwxr-xr-x 5 xtrnaw7 xtrnaw7      5 Mar 15  2017 android-9
-rw-r--r-- 1 xtrnaw7 xtrnaw7 312566 Mar 15  2017 NOTICE
-rw-r--r-- 1 xtrnaw7 xtrnaw7   4465 Mar 15  2017 repo.prop
xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$



In each sub directory for the SDK versions are directories for the CPUs used in Android devices, e.g:

xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$ ls -l platforms/android-24/
total 3
drwxr-xr-x 3 xtrnaw7 xtrnaw7 3 Mar 15  2017 arch-arm
drwxr-xr-x 3 xtrnaw7 xtrnaw7 3 Mar 15  2017 arch-arm64
drwxr-xr-x 3 xtrnaw7 xtrnaw7 3 Mar 15  2017 arch-mips
drwxr-xr-x 3 xtrnaw7 xtrnaw7 3 Mar 15  2017 arch-mips64
drwxr-xr-x 3 xtrnaw7 xtrnaw7 3 Mar 15  2017 arch-x86
drwxr-xr-x 3 xtrnaw7 xtrnaw7 3 Mar 15  2017 arch-x86_64
xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$



In most cases it's the best choice to use the newest sysroot directory tree for the CPU used in your phone, e.g. for the ASUS Zenfone 8 this is

${NDK}/platforms/android-24/arch-arm64

e.g.

xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$ ls -l platforms/android-24/arch-arm64/*
total 6
drwxr-xr-x 22 xtrnaw7 xtrnaw7 91 Mar 15  2017 include
drwxr-xr-x  2 xtrnaw7 xtrnaw7 28 Mar 15  2017 lib
xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$


(see https://developer.android.com/ndk/guides/stable_apis for details)



The compiler and tools to compile the C programs are in sub directories in the directory

${NDK}/toolchains

e.g.:

ls -l toolchains/
xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$ ls -l toolchains/
total 4
drwxr-xr-x 3 xtrnaw7 xtrnaw7 3 Mar 15  2017 aarch64-linux-android-4.9
drwxr-xr-x 3 xtrnaw7 xtrnaw7 3 Mar 15  2017 arm-linux-androideabi-4.9
drwxr-xr-x 3 xtrnaw7 xtrnaw7 3 Jun 26  2022 llvm
drwxr-xr-x 3 xtrnaw7 xtrnaw7 3 Mar 15  2017 mips64el-linux-android-4.9
drwxr-xr-x 3 xtrnaw7 xtrnaw7 3 Mar 15  2017 mipsel-linux-android-4.9
drwxr-xr-x 3 xtrnaw7 xtrnaw7 3 Mar 15  2017 renderscript
drwxr-xr-x 3 xtrnaw7 xtrnaw7 3 Jun 26  2022 x86-4.9
drwxr-xr-x 3 xtrnaw7 xtrnaw7 3 Mar 15  2017 x86_64-4.9
xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$





To compile the C program on a machine running Linux use the executables from the directory

${NDK}/toolchains/x86_64-4.9/prebuilt/linux-x86_64/bin

e.g.:

ls -l /data/develop/android/android-ndk-r14b/toolchains/x86_64-4.9/prebuilt/linux-x86_64/bin
xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$ ls -l /data/develop/android/android-ndk-r14b/toolchains/x86_64-4.9/prebuilt/linux-x86_64/bin
total 18062
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  937592 Mar 15  2017 x86_64-linux-android-addr2line
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  966176 Mar 15  2017 x86_64-linux-android-ar
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 1734464 Mar 15  2017 x86_64-linux-android-as
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  813576 Mar 15  2017 x86_64-linux-android-c++
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  933080 Mar 15  2017 x86_64-linux-android-c++filt
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  813576 Mar 15  2017 x86_64-linux-android-cpp
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 2790568 Mar 15  2017 x86_64-linux-android-dwp
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   27976 Mar 15  2017 x86_64-linux-android-elfedit
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  813576 Mar 15  2017 x86_64-linux-android-g++
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  809480 Mar 15  2017 x86_64-linux-android-gcc
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  809480 Mar 15  2017 x86_64-linux-android-gcc-4.9
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  809480 Mar 15  2017 x86_64-linux-android-gcc-4.9.x
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   25440 Mar 15  2017 x86_64-linux-android-gcc-ar
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   25408 Mar 15  2017 x86_64-linux-android-gcc-nm
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   25408 Mar 15  2017 x86_64-linux-android-gcc-ranlib
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  426056 Mar 15  2017 x86_64-linux-android-gcov
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  462984 Mar 15  2017 x86_64-linux-android-gcov-tool
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 1000280 Mar 15  2017 x86_64-linux-android-gprof
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 4687880 Mar 15  2017 x86_64-linux-android-ld
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 1756288 Mar 15  2017 x86_64-linux-android-ld.bfd
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 4687880 Mar 15  2017 x86_64-linux-android-ld.gold
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  945432 Mar 15  2017 x86_64-linux-android-nm
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 1121336 Mar 15  2017 x86_64-linux-android-objcopy
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 2063256 Mar 15  2017 x86_64-linux-android-objdump
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  966176 Mar 15  2017 x86_64-linux-android-ranlib
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  441976 Mar 15  2017 x86_64-linux-android-readelf
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  937432 Mar 15  2017 x86_64-linux-android-size
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  937560 Mar 15  2017 x86_64-linux-android-strings
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 1121368 Mar 15  2017 x86_64-linux-android-strip
xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$
 


The necessary changes to the Makefile for a C program to create an executable file for execution in the Android operating system are:


1. change the compiler to use to the appropriate C Compiler from the Android NDK (in a lot of Makefiles this is the variable CC)

CC=/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9


2. Add the options

--sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE

to the options for the compiler (CFLAGS)


3. Add the options

--sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -pie

to the options for the linker (LDFLAGS)


4. Remove not necessary libraries from the makefile:

For example the library pthreads is not necessary for Android executables (the functions from pthreads are part of the bionic library in the Android OS)
(see https://developer.android.com/ndk/guides/stable_apis for details)


Note:

If the script ./configure is used to create the make files it's sufficient to define these environment variables before executing ./configure:

export NDK="/data/develop/android/android-ndk-r14b"

# Set this to your minSdkVersion.
#
export API=21

# for the ASUS Zenfone 8 use
#
export TARGET=aarch64-linux-android

export  CFLAGS="--sysroot=${NDK}/platforms/android-${API}/arch-arm64 -fPIE"
export LDFLAGS="--sysroot=${NDK}/platforms/android-
${API}/arch-arm64 -pie"

export CC=${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/${
TARGET}-gcc-4.9
export AR=${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/
${TARGET}-gcc-ar
export LD=${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/
${TARGET}-gcc-ld
export CXX=${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/
${TARGET}-c++
export RANLIB=${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/
${TARGET}-ranlib
export STRIP=${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/
${TARGET}-strip
export AS=${CC}

./configure --host ${TARGET}





For libraries required by an executable that are not part of the Android NDK I recommend to create an additional sysroot environment, e.g.:

mkdir -p /data/develop/android/android_root
mkdir -p /data/develop/android/android_root/usr
mkdir -p /data/develop/android/android_root/usr/bin
mkdir -p /data/develop/android/android_root/usr/sbin
mkdir -p /data/develop/android/android_root/usr/lib
mkdir -p /data/develop/android/android_root/usr/include
mkdir -p /data/develop/android/android_root/usr/man
ln -s ./usr/bin /data/develop/android/android_root/bin
ln -s ./usr/lib /data/develop/android/android_root/lib
ln -s ./usr/sbin /data/develop/android/android_root/sbin


Then use the configure option --prefix=/data/develop/android/android_root/usr to compile and "install" necessary libraries.

To use the include files and libraries from that sysroot environment use the additional compiler option

CFLAGS=-I/data/develop/android/android_root/usr/include

and the additional linker option

LDFLAGS=-L/data/develop/android/android_root/usr/lib



To test the compilation process using the GCC from the Android NDK, I recommend starting by compiling some simple binary files or libraries such as pigz, bvi, or the ncurses library.



In the Android NDK version r14b the script ./build/tools/make_standalone_toolchain.py can be used to create a tool chain directory for a specific environment, e.g:


./build/tools/make_standalone_toolchain.py --arch arm64 --install-dir /data/develop/android/rootdir_r14b


/build/tools/make_standalone_toolchain.py --arch arm64 --install-dir /data/develop/android/rootdir_r14b
xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$ ./build/tools/make_standalone_toolchain.py --arch arm64 --install-dir /data/develop/android/rootdir_r14b
WARNING:__main__:Defaulting to target API 21 (minimum supported target for arm64)
xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$

xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$ ls -l /data/develop/android/rootdir_r14b
total 124
drwxr-xr-x  5 xtrnaw7 xtrnaw7      5 Feb 13 08:36 aarch64-linux-android
-rw-r--r--  1 xtrnaw7 xtrnaw7     11 Mar 15  2017 AndroidVersion.txt
drwxr-xr-x 10 xtrnaw7 xtrnaw7     75 Feb 13 08:36 bin
-rw-r--r--  1 xtrnaw7 xtrnaw7  18002 Mar 15  2017 COPYING
-rw-r--r--  1 xtrnaw7 xtrnaw7  35147 Mar 15  2017 COPYING3
-rw-r--r--  1 xtrnaw7 xtrnaw7   7639 Mar 15  2017 COPYING3.LIB
-rw-r--r--  1 xtrnaw7 xtrnaw7  26527 Mar 15  2017 COPYING.LIB
-rw-r--r--  1 xtrnaw7 xtrnaw7   3324 Mar 15  2017 COPYING.RUNTIME
drwxr-xr-x  4 xtrnaw7 xtrnaw7      4 Feb 13 08:36 include
drwxr-xr-x  7 xtrnaw7 xtrnaw7      8 Feb 13 08:36 lib
drwxr-xr-x  3 xtrnaw7 xtrnaw7      6 Feb 13 08:36 lib64
drwxr-xr-x  3 xtrnaw7 xtrnaw7      3 Feb 13 08:36 libexec
-rw-r--r--  1 xtrnaw7 xtrnaw7   8516 Mar 15  2017 manifest_3362437.xml
-rw-r--r--  1 xtrnaw7 xtrnaw7      0 Mar 15  2017 MODULE_LICENSE_BSD_LIKE
-rw-r--r--  1 xtrnaw7 xtrnaw7      0 Mar 15  2017 MODULE_LICENSE_GPL
-rw-r--r--  1 xtrnaw7 xtrnaw7      0 Mar 15  2017 MODULE_LICENSE_MIT
-rw-r--r--  1 xtrnaw7 xtrnaw7 126349 Mar 15  2017 NOTICE
-rw-r--r--  1 xtrnaw7 xtrnaw7   4465 Mar 15  2017 repo.prop
drwxr-xr-x  5 xtrnaw7 xtrnaw7      5 Feb 13 08:36 share
drwxr-xr-x  3 xtrnaw7 xtrnaw7      3 Mar 15  2017 sysroot
drwxr-xr-x  7 xtrnaw7 xtrnaw7      7 Feb 13 08:36 test
drwxr-xr-x  4 xtrnaw7 xtrnaw7      4 Feb 13 08:36 tools
xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$

xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$ ls -l /data/develop/android/rootdir_r14b/bin
total 91048
-rwxr-xr-x 1 xtrnaw7 xtrnaw7      197 Mar 15  2017 2to3
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   859832 Mar 15  2017 aarch64-linux-android-addr2line
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   888416 Mar 15  2017 aarch64-linux-android-ar
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  1336928 Mar 15  2017 aarch64-linux-android-as
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   776712 Mar 15  2017 aarch64-linux-android-c++
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   855352 Mar 15  2017 aarch64-linux-android-c++filt
-rwxr-xr-x 1 xtrnaw7 xtrnaw7      218 Feb 13 08:36 aarch64-linux-android-clang
-rwxr-xr-x 1 xtrnaw7 xtrnaw7      222 Feb 13 08:36 aarch64-linux-android-clang++
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   772968 Mar 15  2017 aarch64-linux-android-cpp
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  2790568 Mar 15  2017 aarch64-linux-android-dwp
-rwxr-xr-x 1 xtrnaw7 xtrnaw7    27976 Mar 15  2017 aarch64-linux-android-elfedit
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   776712 Mar 15  2017 aarch64-linux-android-g++
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   772616 Mar 15  2017 aarch64-linux-android-gcc
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   772616 Mar 15  2017 aarch64-linux-android-gcc-4.9
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   772616 Mar 15  2017 aarch64-linux-android-gcc-4.9.x
-rwxr-xr-x 1 xtrnaw7 xtrnaw7    25440 Mar 15  2017 aarch64-linux-android-gcc-ar
-rwxr-xr-x 1 xtrnaw7 xtrnaw7    25408 Mar 15  2017 aarch64-linux-android-gcc-nm
-rwxr-xr-x 1 xtrnaw7 xtrnaw7    25408 Mar 15  2017 aarch64-linux-android-gcc-ranlib
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   426056 Mar 15  2017 aarch64-linux-android-gcov
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   462984 Mar 15  2017 aarch64-linux-android-gcov-tool
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   922552 Mar 15  2017 aarch64-linux-android-gprof
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  1913056 Mar 15  2017 aarch64-linux-android-ld
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  1913056 Mar 15  2017 aarch64-linux-android-ld.bfd
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  4687880 Mar 15  2017 aarch64-linux-android-ld.gold
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   867896 Mar 15  2017 aarch64-linux-android-nm
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  1043608 Mar 15  2017 aarch64-linux-android-objcopy
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  1488280 Mar 15  2017 aarch64-linux-android-objdump
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   888416 Mar 15  2017 aarch64-linux-android-ranlib
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   441976 Mar 15  2017 aarch64-linux-android-readelf
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   859704 Mar 15  2017 aarch64-linux-android-size
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   859800 Mar 15  2017 aarch64-linux-android-strings
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  1043640 Mar 15  2017 aarch64-linux-android-strip
drwxr-xr-x 2 xtrnaw7 xtrnaw7        4 Feb 13 08:36 arm64-v8a
drwxr-xr-x 2 xtrnaw7 xtrnaw7        4 Feb 13 08:36 armeabi
drwxr-xr-x 2 xtrnaw7 xtrnaw7        4 Feb 13 08:36 armeabi-v7a
drwxr-xr-x 2 xtrnaw7 xtrnaw7        4 Feb 13 08:36 armeabi-v7a-hard
-rwxr-xr-x 1 xtrnaw7 xtrnaw7    12628 Mar 15  2017 asan_device_setup
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   118848 Mar 15  2017 awk
-rwxr-xr-x 1 xtrnaw7 xtrnaw7      218 Feb 13 08:36 clang
-rwxr-xr-x 1 xtrnaw7 xtrnaw7      222 Feb 13 08:36 clang++
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 41786976 Mar 15  2017 clang38
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 41786976 Mar 15  2017 clang38++
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  3459480 Mar 15  2017 clang-format
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 20736616 Mar 15  2017 clang-tidy
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   502144 Mar 15  2017 FileCheck
-rwxr-xr-x 1 xtrnaw7 xtrnaw7     2945 Mar 15  2017 gcore
-rwxr-xr-x 1 xtrnaw7 xtrnaw7       94 Mar 15  2017 gdb
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  9342192 Mar 15  2017 gdb-orig
-rwxr-xr-x 1 xtrnaw7 xtrnaw7      195 Mar 15  2017 idle
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  2853264 Mar 15  2017 llvm-as
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  2267536 Mar 15  2017 llvm-dis
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  4733336 Mar 15  2017 llvm-link
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  3248048 Mar 15  2017 llvm-symbolizer
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   162752 Mar 15  2017 make
drwxr-xr-x 2 xtrnaw7 xtrnaw7        4 Feb 13 08:36 mips
drwxr-xr-x 2 xtrnaw7 xtrnaw7        4 Feb 13 08:36 mips64
-rwxr-xr-x 1 xtrnaw7 xtrnaw7    38368 Mar 15  2017 ndk-depends
-rwxr-xr-x 1 xtrnaw7 xtrnaw7       87 Mar 15  2017 ndk-gdb
-rwxr-xr-x 1 xtrnaw7 xtrnaw7    24982 Mar 15  2017 ndk-gdb.py
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   880576 Mar 15  2017 ndk-stack
-rwxr-xr-x 1 xtrnaw7 xtrnaw7     1680 Mar 15  2017 ndk-which
-rwxr-xr-x 1 xtrnaw7 xtrnaw7      180 Mar 15  2017 pydoc
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  2153751 Mar 15  2017 python
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  2153751 Mar 15  2017 python2
-rwxr-xr-x 1 xtrnaw7 xtrnaw7  2153751 Mar 15  2017 python2.7
-rwxr-xr-x 1 xtrnaw7 xtrnaw7     1770 Mar 15  2017 python2.7-config
-rwxr-xr-x 1 xtrnaw7 xtrnaw7     1770 Mar 15  2017 python2-config
-rwxr-xr-x 1 xtrnaw7 xtrnaw7     1770 Mar 15  2017 python-config
-rwxr-xr-x 1 xtrnaw7 xtrnaw7     3161 Mar 15  2017 python-config.sh
-rwxr-xr-x 1 xtrnaw7 xtrnaw7    18643 Mar 15  2017 smtpd.py
drwxr-xr-x 2 xtrnaw7 xtrnaw7        4 Feb 13 08:36 x86
drwxr-xr-x 2 xtrnaw7 xtrnaw7        4 Feb 13 08:36 x86_64
-rwxr-xr-x 1 xtrnaw7 xtrnaw7   666280 Mar 15  2017 yasm
xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$

xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$ ls -l /data/develop/android/rootdir_r14b/sysroot/
total 1
drwxr-xr-x 4 xtrnaw7 xtrnaw7 4 Mar 15  2017 usr
xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$

xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$ ls -l /data/develop/android/rootdir_r14b/sysroot/usr
total 6
drwxr-xr-x 20 xtrnaw7 xtrnaw7 89 Mar 15  2017 include
drwxr-xr-x  2 xtrnaw7 xtrnaw7 26 Mar 15  2017 lib
xtrnaw7@fedora01:/data/develop/android/android-ndk-r14b$


In this example, the compiler and the tools are located in the directory /data/develop/android/rootdir_r14b/bin and the sysroot is in the directory /data/develop/android/rootdir_r14b/sysroot.



Notes:

See the section How to compile a C program for Android using the new GCC cross-compiler for instructions to use a newer gcc cross compiler.

The compiler in the current Android NDK is clang. See the section How to compile a C program for Android using the clang from the Android NDK for how to compile a C program using clang from the current Android SDK.


 

How to compile a C program for Android using the clang from the Android NDK



How to compile a C program for Android using clang from the Android NDK


Android is in the end just another Linux and therefore many C programs that were developed for Linux can also be compiled to run in the Android OS.

The tool chain required to compile a C program for Android is part of the Android NDK; the Android NDK can be downloaded from here: https://developer.android.com/ndk/downloads 

The compiler in the current Android NDK is clang; to compile a program for Android using gcc one of the old Android SDK versions with gcc is necessary -- see How to compile a C program for Android using gcc from the Android NDK

Android NDKs are available as tar file -- to install the Android NDK just download the tar file with the Android NDK and untar it.


The example below is for the Android NDK version r25.2 "installed"in the directory /data/develop/android/android-ndk-r25.2 on a machine running the Linux OS.

(NDK=/data/develop/android/android-ndk-r25.2)


The tool chain for compiling a C program for Android using clang is in the directory

${NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin

e.g.

ls toolchains/llvm/prebuilt/linux-x86_64/bin
xtrnaw7@fedora01:/data/develop/android/android-ndk-r25.2$ ls  toolchains/llvm/prebuilt/linux-x86_64/bin
aarch64-linux-android21-clang       armv7a-linux-androideabi24-clang    clang-offload-packager        i686-linux-android31-clang    llvm-debuginfod         llvm-profdata            UnicodeNameMappingGenerator
aarch64-linux-android21-clang++     armv7a-linux-androideabi24-clang++  clang-offload-wrapper         i686-linux-android31-clang++  llvm-debuginfod-find    llvm-profgen             verify-uselistorder
aarch64-linux-android22-clang       armv7a-linux-androideabi26-clang    clang-refactor                i686-linux-android32-clang    llvm-diff               llvm-ranlib              x86_64-linux-android21-clang
aarch64-linux-android22-clang++     armv7a-linux-androideabi26-clang++  clang-rename                  i686-linux-android32-clang++  llvm-dis                llvm-rc                  x86_64-linux-android21-clang++
aarch64-linux-android23-clang       armv7a-linux-androideabi27-clang    clang-repl                    i686-linux-android33-clang    llvm-dlltool            llvm-readelf             x86_64-linux-android22-clang
aarch64-linux-android23-clang++     armv7a-linux-androideabi27-clang++  clang-scan-deps               i686-linux-android33-clang++  llvm-dwarfdump          llvm-readobj             x86_64-linux-android22-clang++
aarch64-linux-android24-clang       armv7a-linux-androideabi28-clang    clang-tidy                    intercept-build               llvm-dwarfutil          llvm-reduce              x86_64-linux-android23-clang
aarch64-linux-android24-clang++     armv7a-linux-androideabi28-clang++  count                         ld                            llvm-dwp                llvm-remark-size-diff    x86_64-linux-android23-clang++
aarch64-linux-android26-clang       armv7a-linux-androideabi29-clang    diagtool                      ld64.lld                      llvm-exegesis           llvm-rtdyld              x86_64-linux-android24-clang
aarch64-linux-android26-clang++     armv7a-linux-androideabi29-clang++  dsymutil                      ld.lld                        llvm-extract            llvm-sim                 x86_64-linux-android24-clang++
aarch64-linux-android27-clang       armv7a-linux-androideabi30-clang    FileCheck                     llc                           llvm-gsymutil           llvm-size                x86_64-linux-android26-clang
aarch64-linux-android27-clang++     armv7a-linux-androideabi30-clang++  git-clang-format              lld                           llvm-ifs                llvm-split               x86_64-linux-android26-clang++
aarch64-linux-android28-clang       armv7a-linux-androideabi31-clang    hmaptool                      lldb                          llvm-install-name-tool  llvm-stress             x86_64-linux-android27-clang
aarch64-linux-android28-clang++     armv7a-linux-androideabi31-clang++  i686-linux-android19-clang    lldb-argdumper                llvm-jitlink            llvm-strings             x86_64-linux-android27-clang++
aarch64-linux-android29-clang       armv7a-linux-androideabi32-clang    i686-linux-android19-clang++  lldb.sh                       llvm-jitlink-executor   llvm-strip              x86_64-linux-android28-clang
aarch64-linux-android29-clang++     armv7a-linux-androideabi32-clang++  i686-linux-android21-clang    lld-link                      llvm-lib                llvm-symbolizer          x86_64-linux-android28-clang++
aarch64-linux-android30-clang       armv7a-linux-androideabi33-clang    i686-linux-android21-clang++  lli                           llvm-libtool-darwin     llvm-tapi-diff          x86_64-linux-android29-clang
aarch64-linux-android30-clang++     armv7a-linux-androideabi33-clang++  i686-linux-android22-clang    lli-child-target              llvm-link               llvm-tblgen              x86_64-linux-android29-clang++
aarch64-linux-android31-clang       bisect_driver.py                    i686-linux-android22-clang++  llvm-addr2line                llvm-lipo               llvm-tli-checker         x86_64-linux-android30-clang
aarch64-linux-android31-clang++     bugpoint                            i686-linux-android23-clang    llvm-ar                       llvm-lto                llvm-undname             x86_64-linux-android30-clang++
aarch64-linux-android32-clang       c-index-test                        i686-linux-android23-clang++  llvm-as                       llvm-lto2               llvm-windres             x86_64-linux-android31-clang
aarch64-linux-android32-clang++     clang                               i686-linux-android24-clang    llvm-bcanalyzer               llvm-mc                 llvm-xray                x86_64-linux-android31-clang++
aarch64-linux-android33-clang       clang++                             i686-linux-android24-clang++  llvm-bitcode-strip            llvm-mca                merge-fdata              x86_64-linux-android32-clang
aarch64-linux-android33-clang++     clang-15                            i686-linux-android26-clang    llvm-bolt                     llvm-ml                 not                      x86_64-linux-android32-clang++
analyze-build                       clang-check                         i686-linux-android26-clang++  llvm-cat                      llvm-modextract         obj2yaml                 x86_64-linux-android33-clang
armv7a-linux-androideabi19-clang    clang-cl                            i686-linux-android27-clang    llvm-cfi-verify               llvm-mt                 opt                      x86_64-linux-android33-clang++
armv7a-linux-androideabi19-clang++  clang-cpp                           i686-linux-android27-clang++  llvm-config                   llvm-nm                 remote_toolchain_inputs  yaml2obj
armv7a-linux-androideabi21-clang    clangd                              i686-linux-android28-clang    llvm-cov                      llvm-objcopy            sancov                   yaml-bench
armv7a-linux-androideabi21-clang++  clang-extdef-mapping                i686-linux-android28-clang++  llvm-c-test                   llvm-objdump            sanstats                 yasm
armv7a-linux-androideabi22-clang    clang-format                        i686-linux-android29-clang    llvm-cvtres                   llvm-opt-report         scan-build
armv7a-linux-androideabi22-clang++  clang-linker-wrapper                i686-linux-android29-clang++  llvm-cxxdump                  llvm-otool              scan-build-py
armv7a-linux-androideabi23-clang    clang-nvlink-wrapper                i686-linux-android30-clang    llvm-cxxfilt                  llvm-pdbutil            scan-view
armv7a-linux-androideabi23-clang++  clang-offload-bundler               i686-linux-android30-clang++  llvm-cxxmap                   llvm-PerfectShuffle     split-file
xtrnaw7@fedora01:/data/develop/android/android-ndk-r25.2$




The sysroot directory with the most the include files and libraries in he Android NDK is located in the directory

${NDK}/toolchains/llvm/prebuilt/linux-x86_64/sysroot

(see https://developer.android.com/ndk/guides/stable_apis for details)



The necessary changes to the Makefile for a C program to create an executable file for execution in the Android operating system using clang are:


1. change the compiler to be used to the appropriate C compiler of the Android NDK (in many Makefiles this is the variable CC)

CC=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android33-clang


2. Add the options

--sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE

to the options for the compiler (CFLAGS)


3. Add the options

--sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -pie

to the options for the linker (LDFLAGS)


4. Remove not necessary libraries from the makefile:

For example the library pthreads is not necessary for Android executables (the functions from pthreads are part of the bionic library in the Android OS).
(see https://developer.android.com/ndk/guides/stable_apis for details)



Note:

If the script ./configure is used to create the make files it's sufficient to define these environment variables before executing ./configure, e.g.:

# for the ASUS Zenfone 8 use
#
export TARGET=aarch64-linux-android

# Set this to your minSdkVersion.
export API=21

export NDK=/data/develop/android/android-ndk-r25.2
export TOOLCHAIN=${NDK}/toolchains/llvm/prebuilt/linux-x86_64

export  CFLAGS="--sysroot ${TOOLCHAIN}/sysroot -fPIE"
export LDFLAGS="--sysroot ${TOOLCHAIN}/sysroot -pie"

export CC=$TOOLCHAIN/bin/$TARGET$API-clang

export AR=${TOOLCHAIN}/bin/llvm-ar
export AS=${CC}
export CXX=${TOOLCHAIN}/bin/$TARGET$API-clang++
export LD=${TOOLCHAIN}/bin/ld
export RANLIB=${TOOLCHAIN}/bin/llvm-ranlib
export STRIP=${TOOLCHAIN}/bin/llvm-strip

./configure --host ${TARGET}



(see also https://developer.android.com/ndk/guides/other_build_systems)




For libraries required by an executable that are not part of the Android NDK I recommend to create an additional sysroot environment, e.g.:

mkdir -p /data/develop/android/android_root
mkdir -p /data/develop/android/android_root/usr
mkdir -p /data/develop/android/android_root/usr/bin
mkdir -p /data/develop/android/android_root/usr/sbin
mkdir -p /data/develop/android/android_root/usr/lib
mkdir -p /data/develop/android/android_root/usr/include
mkdir -p /data/develop/android/android_root/usr/man

ln -s ./usr/bin /data/develop/android/android_root/bin
ln -s ./usr/lib /data/develop/android/android_root/lib
ln -s ./usr/sbin /data/develop/android/android_root/sbin


Then use the configure option --prefix=/data/develop/android/android_root/usr to compile and "install" the necessary libraries.

To use the include files and libaries from that sysroot environment to create executables for Android use the additional compiler option

CFLAGS=-I/data/develop/android/android_root/usr/include

and the additional linker option

LDFLAGS=-L/data/develop/android/android_root/usr/lib




To test the compilation process using the GCC from the Android NDK, I recommend starting by compiling some simple binary files or libraries such as pigz, bvi, or the ncurses library.


Notes

If executing the new binary in the Android OS fails with an error message like this:

ASUS_I006D:/ $  /data/local/tmp/pigz
"/data/local/tmp/pigz": error: Android 5.0 and later only support position-independent executables (-fPIE).
1|ASUS_I006D:/ $


the executable was compiled without the option -fPIE and/or linked without the options -pie.

Use the command readelf to check the compile options for the binary - examples:

readelf output for executables compiled without the options:

ASUS_I006D:/ $ readelf -l /data/local/tmp/pigz  | grep "file type"
Elf file type is EXEC (Executable file)
ASUS_I006D:/ $


readelf output for executables compiled with the options:

ASUS_I006D:/ $ readelf -l /data/local/tmp/pigz  | grep "file type"
Elf file type is DYN (Shared object file)
ASUS_I006D:/ $




To check if a function is available in the libc from an Android NDK use the tool nm, e.g.: to check if the function thread_create is available in the libc use this command:

xtrnaw7@fedora01:~$ nm /data/develop/android/android-ndk-r25.2/toolchains/llvm.dir/sysroot/usr/lib/aarch64-linux-android/26/libc.so | grep -w T | grep thread_create
000000000001b538 T pthread_create
xtrnaw7@fedora01:~$


see also https://android.googlesource.com/platform/bionic/+/master/docs/status.md 






How to compile a C program for Android using a recent GCC cross-compiler


URL: https://xdaforums.com/t/guide-how-to-compile-a-c-program-for-android-using-a-recent-gcc-cross-compiler-in-linux-macos-or-windows.4790485/


How to compile a C program for Android using a recent GCC cross-compiler


The gcc from the Android NDK is quite old and is not supported anymore.

But there is another gcc toolchain available for cross-compiling Android binaries on the PC running Linux, MacOS, or Windows.

The gcc toolchain is available here:

https://github.com/AmanoTeam/android-gcc-cross


The gcc toolchain contains the minimal necessary tools for cross compiling for Android on arm64, arm, x86, or i686 CPUs:

[xtrnaw7@t15g /data/develop/android/cross_compile/android-gcc-16.1.1-cross]$ ls -l bin/aarch64-unknown-linux-android36* bin/aarch64-unknown-linux-android-*
lrwxrwxrwx. 1 xtrnaw7 xtrnaw7       53 May 30 21:44 bin/aarch64-unknown-linux-android36-apt -> ../aarch64-unknown-linux-android24/lib/nouzen/bin/apt
lrwxrwxrwx. 1 xtrnaw7 xtrnaw7       57 May 30 21:44 bin/aarch64-unknown-linux-android36-apt-get -> ../aarch64-unknown-linux-android24/lib/nouzen/bin/apt-get
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7    59816 May 30 21:44 bin/aarch64-unknown-linux-android36-c++
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7    59816 May 30 21:44 bin/aarch64-unknown-linux-android36-clang
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7    59816 May 30 21:44 bin/aarch64-unknown-linux-android36-clang++
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7    59816 May 30 21:44 bin/aarch64-unknown-linux-android36-g++
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7    59816 May 30 21:44 bin/aarch64-unknown-linux-android36-gcc
lrwxrwxrwx. 1 xtrnaw7 xtrnaw7       52 May 30 21:44 bin/aarch64-unknown-linux-android36-nz -> ../aarch64-unknown-linux-android24/lib/nouzen/bin/nz
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  1443040 May 30 21:22 bin/aarch64-unknown-linux-android-addr2line
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  1471496 May 30 21:22 bin/aarch64-unknown-linux-android-ar
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  3272816 May 30 21:22 bin/aarch64-unknown-linux-android-as
lrwxrwxrwx. 1 xtrnaw7 xtrnaw7       33 May 30 21:43 bin/aarch64-unknown-linux-android-c++ -> aarch64-unknown-linux-android-g++
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  1442528 May 30 21:22 bin/aarch64-unknown-linux-android-c++filt
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  2348120 May 30 21:43 bin/aarch64-unknown-linux-android-cpp
lrwxrwxrwx. 1 xtrnaw7 xtrnaw7        3 May 30 21:22 bin/aarch64-unknown-linux-android-dwp -> dwp
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7    35576 May 30 21:22 bin/aarch64-unknown-linux-android-elfedit
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  2348120 May 30 21:43 bin/aarch64-unknown-linux-android-g++
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  2348120 May 30 21:43 bin/aarch64-unknown-linux-android-gcc
lrwxrwxrwx. 1 xtrnaw7 xtrnaw7       33 May 30 21:43 bin/aarch64-unknown-linux-android-gcc-16 -> aarch64-unknown-linux-android-gcc
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7    39160 May 30 21:43 bin/aarch64-unknown-linux-android-gcc-ar
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7    39160 May 30 21:43 bin/aarch64-unknown-linux-android-gcc-nm
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7    39160 May 30 21:43 bin/aarch64-unknown-linux-android-gcc-ranlib
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  1358184 May 30 21:43 bin/aarch64-unknown-linux-android-gcov
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  1169744 May 30 21:43 bin/aarch64-unknown-linux-android-gcov-dump
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  1194328 May 30 21:43 bin/aarch64-unknown-linux-android-gcov-tool
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  1517856 May 30 21:22 bin/aarch64-unknown-linux-android-gprof
lrwxrwxrwx. 1 xtrnaw7 xtrnaw7       36 May 30 21:22 bin/aarch64-unknown-linux-android-ld -> aarch64-unknown-linux-android-ld.bfd
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  3944688 May 30 21:22 bin/aarch64-unknown-linux-android-ld.bfd
lrwxrwxrwx. 1 xtrnaw7 xtrnaw7        7 May 30 21:22 bin/aarch64-unknown-linux-android-ld.gold -> ld.gold
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7 44289368 May 30 21:43 bin/aarch64-unknown-linux-android-lto-dump
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  1464256 May 30 21:22 bin/aarch64-unknown-linux-android-nm
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  1597512 May 30 21:22 bin/aarch64-unknown-linux-android-objcopy
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  3580296 May 30 21:22 bin/aarch64-unknown-linux-android-objdump
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7     1435 May 30 21:43 bin/aarch64-unknown-linux-android-pkg-config
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  1467400 May 30 21:22 bin/aarch64-unknown-linux-android-ranlib
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  1076488 May 30 21:22 bin/aarch64-unknown-linux-android-readelf
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  1446880 May 30 21:22 bin/aarch64-unknown-linux-android-size
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  1455232 May 30 21:22 bin/aarch64-unknown-linux-android-strings
-rwxr-xr-x. 1 xtrnaw7 xtrnaw7  1562408 May 30 21:22 bin/aarch64-unknown-linux-android-strip
[xtrnaw7@t15g /data/develop/android/cross_compile/android-gcc-16.1.1-cross]$


The necessary include files and libraries for the sysroot are also in the archive. Therefore, the Android NDK is not necessary to use the gcc cross-compiler.

As of 01.06.2026 the gcc compiler in that repository is gcc 16.1.1.


Notes

The binaries are also available for armv7, i686, and x86_64 target CPUs.
The API version dependent binaries are available for the API version 21 to the API version 36 (= Android 16).

Other necessary tools, such as make, should be installed using the standard installation procedure in the OS (e.g. dnf, apt, pacman, etc for Linux).


Note

To install the gcc toolchain, download and unpack the tar file with the binaries for your OS in an empty directory.


To use the gcc toolchain, add the directory with the binaries to the PATH variable.


Examples:

create a sample C program
cat  > /data/local/tmp/sysroot/helloworld_in_c.c   <<-\EOT
#include <stdio.h>

int main() {
    printf("Hello, World from a C program!\n");

#ifdef __clang__
    printf("Compiled with Clang %d.%d.%d\n", __clang_major__, __clang_minor__, __clang_patchlevel__);
#elif defined(__GNUC__)
    printf("Compiled with GCC %d.%d.%d\n", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
#else
    printf("Compiled with an unknown compiler\n");
#endif

    return 0;
}
EOT



create a sample C++ program
cat >/data/local/tmp/sysroot/helloworld_in_c++.cpp <<-\EOT

#include <iostream>  // include the input-output stream library

int main() {
    std::cout << "Hello, World from a C++ program!" << std::endl;  // output the message to the console


#ifdef __clang__
    std::cout << "Compiled with Clang "
              << __clang_major__ << "."
              << __clang_minor__ << "."
              << __clang_patchlevel__ << std::endl;
#elif defined(__GNUC__)
    std::cout << "Compiled with GCC "
              << __GNUC__ << "."
              << __GNUC_MINOR__ << "."
              << __GNUC_PATCHLEVEL__ << std::endl;
#else
    std::cout << "Compiled with an unknown compiler" << std::endl;
#endif

    std::cout << "Compiler version: " << __VERSION__ << std::endl;

   return 0;  // indicate successful completion of the program

}
EOT
 


Compile a C program


# use the Android API 36
#
[xtrnaw7@t15g /data/develop/android/cross_compile]$ export API=36
[xtrnaw7@t15g /data/develop/android/cross_compile]$

[xtrnaw7@t15g /data/develop/android/cross_compile]$ aarch64-unknown-linux-android${API}-gcc \
    --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android${API} \
    ./helloworld_in_c.c -o ./helloworld_in_c
[xtrnaw7@t15g /data/develop/android/cross_compile]$

[xtrnaw7@t15g /data/develop/android/cross_compile]$ ls -l helloworld_in_c
-rwxrwxr-x. 1 xtrnaw7 xtrnaw7 37464 Jun  1 10:40 helloworld_in_c
[xtrnaw7@t15g /data/develop/android/cross_compile]$

[xtrnaw7@t15g /data/develop/android/cross_compile]$ file helloworld_in_c
helloworld_in_c: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, BuildID[sha1]=4a75ab71aa8f31609bdb20c22854a495f2ff1b8e, for Android 36, built by NDK r30-beta1 (14904198), not stripped
[xtrnaw7@t15g /data/develop/android/cross_compile]$


# Test the binary

[xtrnaw7@t15g /data/develop/android/cross_compile]$ adb push helloworld_in_c /data/local/tmp/helloworld_in_c  && echo ; adb shell /data/local/tmp/helloworld_in_c
helloworld_in_c: 1 file pushed, 0 skipped. 154.2 MB/s (37464 bytes in 0.000s)

Hello, World from a C program!
Compiled with GCC 16.1.1
[xtrnaw7@t15g /data/develop/android/cross_compile]$


[xtrnaw7@t15g /data/develop/android/cross_compile]$  adb shell ldd /data/local/tmp/helloworld_in_c
    linux-vdso.so.1 => [vdso] (0x76abe6b000)
    libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x76a6e99000)
    libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x76aab08000)
[xtrnaw7@t15g /data/develop/android/cross_compile]$



Compile a C++ program


# use the Android API 36
#
[xtrnaw7@t15g /data/develop/android/cross_compile]$ export API=36
[xtrnaw7@t15g /data/develop/android/cross_compile]$

[xtrnaw7@t15g /data/develop/android/cross_compile]$ aarch64-unknown-linux-android${API}-g++ \
    -static-libgcc \
    -static-libstdc++ \
    --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android${API} \
    helloworld_in_c++.cpp \
    -o helloworld_in_c++
[xtrnaw7@t15g /data/develop/android/cross_compile]$

[xtrnaw7@t15g /data/develop/android/cross_compile]$ ls -l helloworld_in_c++
-rwxrwxr-x. 1 xtrnaw7 xtrnaw7 1586080 Jun  1 10:43 helloworld_in_c++
[xtrnaw7@t15g /data/develop/android/cross_compile]$

[xtrnaw7@t15g /data/develop/android/cross_compile]$ file helloworld_in_c++
helloworld_in_c++: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, BuildID[sha1]=eff5edee9026960f5c7a44f0d61ba145ef535e0c, for Android 21, built by NDK r30-beta1 (14904198), with debug_info, not stripped
[xtrnaw7@t15g /data/develop/android/cross_compile]$


# Test the binary

[xtrnaw7@t15g /data/develop/android/cross_compile]$ adb push helloworld_in_c++ /data/local/tmp/helloworld_in_c++ && echo && adb shell /data/local/tmp/helloworld_in_c++
helloworld_in_c++: 1 file pushed, 0 skipped. 68.3 MB/s (1586080 bytes in 0.022s)

Hello, World from a C++ program!
Compiled with GCC 16.1.1
Compiler version: 16.1.1 20260530
[xtrnaw7@t15g /data/develop/android/cross_compile]$


[xtrnaw7@t15g /data/develop/android/cross_compile]$ adb shell ldd /data/local/tmp/helloworld_in_c++
    linux-vdso.so.1 => [vdso] (0x7d673a8000)
    libm.so => /apex/com.android.runtime/lib64/bionic/libm.so (0x7d625c6000)
    libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x7d62652000)
    libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x7d62612000)
[xtrnaw7@t15g /data/develop/android/cross_compile]$


Notes

The gcc ignores include directories specified with the parameter -I whose names are already used for directories with header files in the build-in NDK, such as sysroot/usr/include.

You can bypass this check by renaming the directory to something else (e.g., /develop/sysroot/include or simply /develop/include), and gcc should then accept it.

Example:

[xtrnaw7@t15g /data/develop/android/cross_compile]$ echo | aarch64-unknown-linux-android36-gcc -I/data/local/tmp/develop/sysroot/usr/include -E -Wp,-v - 2>&1 | grep -A 20 "search starts"
#include "..." search starts here:
#include <...> search starts here:
 /data/develop/android/cross_compile/android-gcc-16.1.1-cross/lib/gcc/aarch64-unknown-linux-android/16/include
 /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36/include
 /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36/include/aarch64-unknown-linux-android
End of search list.
# 0 "<stdin>"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "<stdin>"
[xtrnaw7@t15g /data/develop/android/cross_compile]$

->  the gcc ignores the directory /data/local/tmp/develop/sysroot/usr/include


[xtrnaw7@t15g /data/develop/android/cross_compile]$ echo | aarch64-unknown-linux-android36-gcc -I/data/local/tmp/develop/usr/include -E -Wp,-v - 2>&1 | grep -A 20 "search starts"
#include "..." search starts here:
#include <...> search starts here:
 /data/local/tmp/develop/usr/include
 /data/develop/android/cross_compile/android-gcc-16.1.1-cross/lib/gcc/aarch64-unknown-linux-android/16/include
 /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36/include
 /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36/include/aarch64-unknown-linux-android
End of search list.
# 0 "<stdin>"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "<stdin>"
[xtrnaw7@t15g /data/develop/android/cross_compile]$

->  the gcc uses the directory /data/local/tmp/develop/usr/include  


Trouble Shooting

If the build fails because of a missing file in the directory ./asm, create the symbolic link ./asm for the directory include/asm-generic:

For example for the files for arm64 (= aarch64) CPUs:

  cd /data/develop/android/cross_compile/android-gcc-16.1.1-cross
  if [ ! -r ./aarch64-unknown-linux-android/include/asm ] ; then

    if [ -r ./aarch64-unknown-linux-android/include/asm-generic ] ; then
      ln -s ./asm-generic ./aarch64-unknown-linux-android/include/asm
    fi
  fi


see Examples for compiling programs using the new GCC cross-compiler for other examples for using the new gcc cross-compiler




History of this entry

01.06.2026

initial release





How to compile a C program for Android in Android using clang



How to install clang on the phone


How to install clang on the phone
I 've created various Magisk Modules to install a clang tool chain on the phone -- see http://bnsmb.de/Magisk_Modules.html for the list of Magisk Modules available.

There are Magisk Modules to install clang19, clang20 or clang21.

These Magisk Modules only conatain the minimum required tools to compile a C or C++ program. But there are also Magisk modules with other tools, for example autoconf, bison, flex, perl, python, cmake, gdb, etc.



History of this entry

19.04.2026

initial release



 

How to install a toolchain for clang19 on phones without root access


URL: https://xdaforums.com/t/guide-how-to-install-a-toolchain-for-clang-on-phones-without-root-access.4710235/


How to install a toolchain for clang19 on phones without root access

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 Compiling C programs in Android in Termux for details about using Termux)


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

clang19_toolchain*tar.gz


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

The toolchain contains :

clang 19.0 binaries and files
gcc 16.1.1 binaries and files

make
cmake
ninja
the autoconfools, 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.06.2026 the files from the Android NDK versions r27d, r28b, and r29 are part of the tar file.

tar files with the necessary files from other Android NDK versions are available here: http://bnsmb.de/files/public/Android/archive/ndk_for_clang19_toolchain/


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 extracted TAR file requires approximately 3.8 GB of disk space. It is recommended that you have at least an additional 512 MB of free disk space available for temporary files.

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 clang 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 clang toolchain. The script also initializes the OpenSSH config files and creates the necessary ssh host keys to start the sshd on the phone.

Please note that the sshd from the clang19 toolchain only supports connections via a public SSH key. The sshd's authorized_keys file is located at /data/local/tmp/sysroot/etc/ssh/authorized_keys; the config file for the sshd is /data/local/tmp/sysroot/etc/ssh/sshd_config.

The script only needs to be executed once (but it can be executed more than once without problems).


Example output of create_clang19_env
ASUS_I006D:/ $ date
Sun Jun  7 10:12:11 CEST 2026
ASUS_I006D:/ $

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

Creating the directory "/data/local/tmp/sysroot/tmp" ...
Correcting the permissions for "/data/local/tmp/sysroot/var/tmp" ...

Creating necessary directories if they are missing ...
Creating the directory "/data/local/tmp/sysroot/./var/run" ....
Creating the directory "/data/local/tmp/sysroot/./var/log" ....
Creating the directory "/data/local/tmp/sysroot/./var/empty" ....
Creating the directory "/data/local/tmp/sysroot/./var/lib" ....
Creating the directory "/data/local/tmp/sysroot/./var/mail" ....
Creating the directory "/data/local/tmp/sysroot/./var/lock" ....
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 222448 2026-06-05 19:17 /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 59737567 2026-03-25 16:58 r27d.tar.gz
-rw-rw-r-- 1 shell shell 72213190 2026-03-25 16:58 r28b.tar.gz
-rw-rw-r-- 1 shell shell 78442811 2026-03-25 16:58 r29.tar.gz

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

Processing the tar file "r29.tar.gz" ...
The tar file contains the NDK "r29"
Unpacking the tar file "r29.tar.gz" ...
 ... tar file "r29.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" ...
Changing the owner of the directory "/data/local/tmp/sysroot/var/empty" to "root" ...

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
The directory "/data/local/tmp/sysroot/var/mail" already exists
The directory "/data/local/tmp/sysroot/var/empty" already exists
The directory "/data/local/tmp/sysroot/var/run" already exists
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:wAxwHaThix5rKElzozTB9Q9jbig4T15bRSGNz0Yyp9o shell@localhost
The key's randomart image is:
+---[ECDSA 256]---+
|  .o+o++o.       |
|. .o.*=o+        |
| o  o=+O.        |
|. ..+.=o+        |
|o*++o=.oS        |
|oO*++oE          |
|+.* .            |
|..               |
|                 |
+----[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:r9P+a0/7TAx44GF0Yw5j4Hn+1+c2FfbFdcv1d0cmJ7I shell@localhost
The key's randomart image is:
+--[ED25519 256]--+
|          ..= +  |
|         . +.*o.B|
|          o =ooB*|
|           =E+ =B|
|        S   + + B|
|         .   o o+|
|         ..   o B|
|        ... .. Bo|
|        .o.ooooo=|
+----[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:Bwa4duToKegthAPRbv28JaFRWFjloFHSVn50hwkCrug shell@localhost
The key's randomart image is:
+---[RSA 3072]----+
| .  oOB++ o..o.  |
|. . +=== o .o.   |
| o ..B. = .      |
|. o.*.+. o       |
|oo.o.B .S .      |
|+o. + + ..       |
|o.E.   +         |
| 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.124

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

scp -P 9022 [source_file]  192.168.1.124:[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 clang 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
Note

These config changes are optional and not required to use the clang toolchain. The config changes apply globally to all Android sessions, but are only temporary until the phone is rebooted.


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.


Example output of "source /data/local/tmp/sysroot/bin/init_clang19_env"
ASUS_I006D:/ $ date
Fri Jun  5 19:21:33 CEST 2026
ASUS_I006D:/ $

ASUS_I006D:/ $ source /data/local/tmp/sysroot/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:/apex/com.android.virt/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/gcc/bin/gcc-toolchain:/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 ...
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
htop=/data/local/tmp/sysroot/usr/bin/htop
rsync=/data/local/tmp/sysroot/usr/bin/rsync
unrar=/data/local/tmp/sysroot/usr/bin/unrar
vim=/data/local/tmp/sysroot/usr/bin/vim
zstd=/data/local/tmp/sysroot/usr/bin/zstd
zstdcat=/data/local/tmp/sysroot/usr/bin/zstdcat
zstdgrep=/data/local/tmp/sysroot/usr/bin/zstdgrep
zstdless=/data/local/tmp/sysroot/usr/bin/zstdless
zstdmt=/data/local/tmp/sysroot/usr/bin/zstdmt
scp=/data/local/tmp/sysroot/usr/bin/scp
sftp=/data/local/tmp/sysroot/usr/bin/sftp
ssh=/data/local/tmp/sysroot/usr/bin/ssh
ssh-keygen=/data/local/tmp/sysroot/usr/bin/ssh-keygen
sshd=/data/local/tmp/sysroot/usr/sbin/sshd

Root access is enabled on this machine

Adding missing SELinux policies using "/product/bin/magiskpolicy" ...
Enabling socket access for the user "shell" (this is necessary to use tmux or ssh-agent)...
Enabling icmp_socket access for the user "shell" (this is necessary to use mtr)...
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" ...


Changing the working directory to "/data/local/tmp/develop" ...
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop $



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 clang19 toolchain can be used.

Use

sh /data/local/tmp/sysroot/bin/init_clang19_env help

to print the usage help for the script:

sh /data/local/tmp/sysroot/bin/init_clang19_env help
ASUS_I006D:/ $ date
Wed Mar 18 14:09:11 CET 2026
ASUS_I006D:/ $

ASUS_I006D:/ $ sh /data/local/tmp/sysroot/bin/init_clang19_env --help

Usage: . /data/local/tmp/sysroot/bin/init_clang19_env [-h|--help] [init] [var=value] [examples] [nocpucheck] [run "command1; command2; ..."]

 
init        - clear the used environment 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
run         - init the environment; run the commands and exit

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

To run only one or more commands use the parameter "run", e.g. to compile the examples use the command:

sh /data/local/tmp/sysroot/bin/init_clang19_env run "/data/local/tmp/sysroot/compile_examples.sh"

ASUS_I006D:/ $



To only execute one or more commands using the clang19 environment use the syntax

sh /data/local/tmp/sysroot/bin/init_clang19_env run "command1 ; command2; ..."


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


The default Android NDK version set by the script init_clang19_env is r27d . To use another Android NDK version set the environment variable NDK before intializing the clang19 environment.


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:

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

-> the symbol __fpending is defined in the libc from API version 23 and newer.





Other example
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.




Using the gcc/g++ compiler from the toolchain

Since version 2.0.0 the toolchain also contains the compilers gcc and g++ and the necessary tools to create executables and libraries using these compilers.


[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $ gcc --version
aarch64-unknown-linux-android-gcc (GCC) 16.1.1 20260529
Copyright (C) 2026 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

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

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $ g++ --version
aarch64-unknown-linux-android-g++ (GCC) 16.1.1 20260529
Copyright (C) 2026 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

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


The clang19 toolcains contains different gcc/g++ binaries for the various Android SDK versions. The wrapper scripts for gcc and g++ use the binaries for the Android SDK version defined in the environment variable API. To use the gcc/g++ for another Android SDK version, set the environment variable API before calling ]gcc/g++.

Example:

[clang19 toolchain] 2|ASUS_I006D:/data/local/tmp/sysroot $ echo $API
31
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $ gcc  -dM -E - < /dev/null | grep "#define __ANDROID_MIN_SDK_VERSION__" 
#define __ANDROID_MIN_SDK_VERSION__ 31
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $ API=36  gcc  -dM -E - < /dev/null | grep "#define __ANDROID_MIN_SDK_VERSION__"  
#define __ANDROID_MIN_SDK_VERSION__ 36
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $


The default Android SDK version hardcoded in the wrapper scripts is 36:

[clang19 toolchain] 1|ASUS_I006D:/data/local/tmp/sysroot $ ( unset API ; gcc  -dM -E - < /dev/null | grep "#define __ANDROID_MIN_SDK_VERSION__" )
#define __ANDROID_MIN_SDK_VERSION__ 36
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $


The compiler gcc and g++ use the directory /data/local/tmp/sysroot/usr/lib/android-gcc-cross as sysroot; they do not use the files from the Android NDKs in /data/local/tmp/sysroot/usr/ndk.


Note that the gcc and g++ compiler ignore include directories starting with ./sysroot.

Example:

[clang19 toolchain] [shell@localhost /data/local/tmp/develop]$ gcc -O0 -g -o nmon  lmon16s.c -I/data/local/tmp/develop/sysroot/usr/include -L/data/local/tmp/develop/sysroot/usr/lib -lncurses -lm
lmon16s.c:58:10: fatal error: ncurses.h: No such file or directory
   58 | #include <ncurses.h>
      |          ^~~~~~~~~~~
compilation terminated.
[clang19 toolchain] [shell@localhost /data/local/tmp/develop]$

[clang19 toolchain] [shell@localhost /data/local/tmp/develop]$ ls -l /data/local/tmp/develop/sysroot/usr/include/ncurses.h
lrwxrwxrwx 1 shell shell 16 2026-05-30 20:51 /data/local/tmp/develop/sysroot/usr/include/ncurses.h -> ncurses/curses.h
[clang19 toolchain] [shell@localhost /data/local/tmp/develop]$


To "fix" that issue, rename the directory or create a symbolic link:

[clang19 toolchain] [shell@localhost /data/local/tmp/develop]$ ln -s /data/local/tmp/develop/sysroot /data/local/tmp/develop/dev
[clang19 toolchain] [shell@localhost /data/local/tmp/develop]$

[clang19 toolchain] [shell@localhost /data/local/tmp/develop]$ gcc -O0 -g -o nmon  lmon16s.c -I/data/local/tmp/develop/dev/usr/include -L/data/local/tmp/develop/dev/usr/lib -lncurses -lm
[clang19 toolchain] [shell@localhost /data/local/tmp/develop]$

[clang19 toolchain] [shell@localhost /data/local/tmp/develop]$ ls -l nmon
-rwxrwxrwx 1 shell shell 276240 2026-06-07 16:20 nmon
[clang19 toolchain] [shell@localhost /data/local/tmp/develop]$

[clang19 toolchain] [shell@localhost /data/local/tmp/develop]$ file nmon
nmon: ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), BuildID=61a569014a3c334d0e88e2748ad6ab837dee5613, for Android 31, built by NDK r30-beta1 (14904198), not stripped
[clang19 toolchain] [shell@localhost /data/local/tmp/develop]$


See the here for more infos about the gcc/g++ compiler.


The gcc toolchain was copied from this repository:

https://github.com/AmanoTeam/android-gcc-cross


The important directories in the tar file are:

Directory
Content
Comment
/data/local/tmp/sysroot/bin a few binaries and symbolic links for the tools

/data/local/tmp/sysroot/usr/bin
binaries for the tools

/data/local/tmp/sysroot/usr/lib
libraries for the tools

/data/local/tmp/sysroot/usr/libexec
helper files and binaries for the tools

/data/local/tmp/sysroot/etc
config 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/share
data files for the tools

/data/local/tmp/sysroot/usr/ndk/#ndkversion#
#ndkversion# is the NDK version
/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




/data/local/tmp/sysroot/usr/gcc/bin/gcc-toolchain
wrapper scripts and symbolic links for the binaries in the gcc/g++ toolchain

/data/local/tmp/sysroot/usr/lib/android-gcc-cross/bin
binaries from the gcc/g++ toolchain

/data/local/tmp/sysroot/usr/lib/android-gcc-cross
sysroot directory for the gcc and g++



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.

The toolchain also contains a script to compile all test programs:

compile_examples.sh



Output of the script ./compile_examples.sh
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $ date
Fri Jun  5 19:27:14 CEST 2026
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $

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

*** Testing the compiler "clang" ....

Hello, World from a C program!
Compiled with Clang 19.0.0

*** Testing the compiler "clang++" ...

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)

*** Testing the assembler from clang ...

Hello, World from an assembler program compiled with clang!

*** Testing the assembler from the binutils ...

Hello, World from an assembler program compiled with as and ld from the binutils!

*** Testing the compiler "gcc" ...

Hello, World from a C program!
Compiled with GCC 16.1.1

*** Testing the compiler "g++" ...

Hello, World from a C++ program!
Compiled with GCC 16.1.1
Compiler version: 16.1.1 20260529

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


Notes


Most of the binaries in the clang19 toolchain are tested in Android 13 and Android 16; they should also work in Android 12, Android 14, and Android 15,


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

grep "^#" README | cut -c2- -d " "

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $ date
Fri Jun  5 19:28:17 CEST 2026
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $ grep "^#" README | cut -f2- -d " "
The tools included in the tar file with the clang19 toolchain are:

clang 19.0.0
gcc 16.1.1
cmake 3.30.4, 4.0.1, and 4.3.0
ninja 1.13.1
make 4.4.1
meson 1.11.1
binutils 2.45 (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.21
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
mksh @(#)MIRBSD KSH R59 2025/06/02

bison 3.8
flex 2.6.4

gdb 17.2 (dynamically and statically linked binaries)

rsync 3.4.1

wget 2.2.0
curl 8.19.0

perl 5.40
python 3.14
pip 26.1.2
tcl 9.0
lua 5.4.8
sqlite3 3.51.1

sshd/ssh 10.0p2
OpenSSL 3.5.6 and 4.0.0

git 2.49
git-lfs 3.7.1

gpg 1.4.3

dig 9.11.37
mtr 0.96
ngrep 1.48.3

nano 9.0, 8.7.1, and nano 6.4
vim 9.2
ed 1.21
bvi /bmore 1.5.0 (a hex editor)
hexcurse 1.60.0 (a hex editor)

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
find 4.9
xtargs 4.9
bc 1.08.2
less 679
htop 3.4.1
btop 1.4.4 (btop needs root access)
strace 6.18

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)
  in the directories /data/local/tmp//usr/androidsdk35_0_2/*-tools
  (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.4 (openvpn requires root access)
stunnel 5.77  (stunnel is a proxy designed to add TLS encryption functionality to existing clients and servers without any changes in the programs code, https://www.stunnel.org/)

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)
darkhttpd 1.17 (a simple webserver; see https://github.com/emikulic/darkhttpd)

protoc v32.1.0 (currently the binary only)

various compression tools:

7zz 26.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 7.20 beta 2
lzip 1.25

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




The binary files and libraries in the tar file are compiled for arm64 CPUs. Therefore the init script for the module, /data/local/tmp/sysroot/bin/init_clang19_env, uses the binary /data/local/tmp/sysroot/bin/testcpu to test, if binaries for arm64 can be executed.


Since version 1.4.0 of the toolchain the test for the execution permissions like this

 [ -x /bin/sh ] && echo ok

works also for non-root user in the bash binary contained in the tar archive.


Some standard Android programs do not work very well with the new binaries in /data/local/tmp/sysroot/usr/bin -- therefore it is recommended that
/system/bin and /system_ext/bin are placed in the PATH variable before /data/local/tmp/sysroot/usr/bin.


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.

To use the file, add the statement

#include <add_missing_definitions.h>

to the source file (but please check the comments at the top of the file before using it)

As of 21.06.2026 the include files add these symbols:

//
// include file with standard definitions missing in the libc from Android
//
// 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
//   quad_t
//   u_quad_t
//   short
//   PTR
//
// This file defines the functions
//   strverscmp
//   versionsort
//   getdtablesize
//   index
//   rindex
//   catopen
//   catgets
//   catclose
//   nl_langinfo
//   getpwent
//   endpwent
//   CloseSocket
//   mktime_z
//   bzero
//   tzalloc
//   tzfree
//   localtime_rz
//   mktime_z
//   android_getpass
//   bcmp
//   ldexpl
//   frexpl
//
// This file defines the macros
//
//   __GNUC_PREREQ
//   isblank
//   min
//   max
//


The file is also available here: add_missing_definitions.h


Some configure scripts and make files for standard Unix tools use libraries that are not available (and not needed) in Android, e.g. libpthread.so.

A dummy (= empty) libpthread.so is part of the clang19 toolchain:

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $ ls -l usr/lib/libpthread.*                                                                                                           
-rw-r--r-- 1 shell shell 1218 2025-09-21 15:04 usr/lib/libpthread.a
-rw-r--r-- 1 shell shell 5272 2025-09-21 15:04 usr/lib/libpthread.so
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $


To create another dummy (empty) library to satisfy the requirements of these configure scripts or make files the script

create_dummy_lib.sh

can be used.

Example:

Create the dummy library libutil.so :

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

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot/usr/lib $ create_dummy_lib.sh util
Creating the library "libutil" ....
-rw-rw-rw- 1 shell shell 1218 2025-12-21 17:47 libutil.a
-rwxrwxrwx 1 shell shell 5272 2025-12-21 17:47 libutil.so
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot/usr/lib $



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)


To list the installed Perl modules, use the command instmodsh. Use the executable cpan to add other Perl modules. Please note that cpan does not work very well with the crippled Unix tools (like gzip) from Android. Therefore, it's recommended to use cpan like this in the clang19 toolchain environment:

PATH=/data/local/tmp/sysroot/usr/bin:$PATH cpan


The pre-installed Perl modules in the clang19 toolchain are:

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop $ date
Sat Mar 21 07:49:46 CET 2026
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop $
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop $ instmodsh
Available commands are:
   l            - List all installed modules
   m <module>   - Select a module
   q            - Quit the program
cmd? l
Installed modules are:
   CPAN
   CPAN::DistnameInfo
   Perl
   Term::ReadKey
   Term::ReadLine
cmd? q
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop $


Use the command pip list to list all installed Python modules. The pre-installed Python modules in the clang19 toolchain are:

[clang19 toolchain] 130|ASUS_I006D:/data/local/tmp/sysroot $ date
Fri Jun  5 19:51:32 CEST 2026
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $ pip list
Package         Version
--------------- -------
build           1.4.4
click           8.3.3
execnet         2.1.2
iniconfig       2.3.0
invoke          3.0.3
meson           1.11.1
packaging       26.1
pip             26.1.2
pip-tools       7.5.3
pluggy          1.6.0
Pygments        2.20.0
pyproject_hooks 1.2.0
pytest          9.0.3
pytest-xdist    3.8.0
setuptools      82.0.1
sh              2.2.2
wheel           0.47.0
[clang19 toolchain] ASUS_I006D:/data/local/tmp/sysroot $



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"

See here for an example usage for gdb.

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 Examples for using the clang19 toolchain on the phone for examples for using the clang19 toolchain


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

There is also a repository with the clang19 toolchain GitHub  https://github.com/bnsmb/clang19_toolchain_for_android



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.


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 /]$

when executing of the binaries 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:/ $


Note that since version 1.6.0 all binaries in the clang19 toolchain do not need the library libc++_shared.so anymore.

See here for instructions to create a binary with clang++ that does not need the library libc++_shared.so.




If executing a binary fails with an error about missing libraries like this

[clang19 toolchain] TB351FU HA20PJMD:/data/local/tmp/develop/nano-8.4 $ ./myconfigure                                                                               
CANNOT LINK EXECUTABLE "printf": cannot find "libselinux.so" from verneed[1] in DT_NEEDED list for "/system/bin/toybox"
CANNOT LINK EXECUTABLE "sed": cannot find "libselinux.so" from verneed[1] in DT_NEEDED list for "/system/bin/toybox"
CANNOT LINK EXECUTABLE "expr": cannot find "libselinux.so" from verneed[1] in DT_NEEDED list for "/system/bin/toybox"
CANNOT LINK EXECUTABLE "sed": cannot find "libselinux.so" from verneed[1] in DT_NEEDED list for "/system/bin/toybox"
CANNOT LINK EXECUTABLE "sed": cannot find "libselinux.so" from verneed[1] in DT_NEEDED list for "/system/bin/toybox"
CANNOT LINK EXECUTABLE "printf": cannot find "libselinux.so" from verneed[1] in DT_NEEDED list for "/system/bin/toybox"
[clang19 toolchain] 1|TB351FU HA20PJMD:/data/local/tmp/develop/nano-8.4 $

add the directory with the file libselinux.so from your Android version to the variable LD_LIBRARY_PATH; this is in most cases the directory /system/lib64:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/system/lib64




The toolchain can also be used in a 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.



Update 23.04.2025

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



Update 29.04.2025

see How to create Magisk Modules that install new files in /system for some tips for creating Magisk Modules on the phone.



Update 11.07.2025

see here for a virtual disk image with the clang19 toolchain that can be used via overlay mount (Note that to use overlay mounts root access is required)


Update 12.03.2026

see here for a Magisk module to start or stop the sshd from the clang19 toolchain. The Magisk Module also installs the script init_clang19_toolchain in /system/bin to init the clang19 toolchain environment.





History of this entry


20.06.2026

adapted the documentation for version 2.0.0 21.06.2026

20.03.2026

adapted the documentation for version 1.7.0 21.03.2026

12.03.2026

added the link to the Magisk module to start or stop the sshd from the clang19 toolchain

26.01.2026

added the infos about how to install Perl Modules

20.01.2026

adapted the documentation for version 1.6.0 21.01.2026

28.10.2025

added the trouble shooting section

21.09.2025

updated the documentation to match the new version 1.5.0 21.09.2025

21.07.2025

updated the documentation to match the new version 1.4.0 21.07.2025

11.07.2025

added the link to the documentation for the virtual disk with the clang19 toolchain that can be used via overlay mount

21.05.2025

updated the documentation to match the new version 1.3.0 21.05.2025

22.01.2025

added links to the examples for using the clang19 toolchain

25.01.2025

added the infos about the github repository with libraries and include files

24.03.2025

updated the documentation to match the new version 1.2.0 23.03.2025

26.12.2024

initial release

 
 

How to install clang20 on phones without root access


URL: https://xdaforums.com/t/guide-how-to-install-clang20-on-phones-without-root-access.4732382/


How to install clang20 on phones without root accesss

For phones with root access and installed Magisk, the clang version 20 can be installed using a Magisk Module (see here for details)

For phones without root access this approach is not possible.

To install clang version 20 (clang20 in the rest of this HowTo) on a phone without root access the tar file

clang20_for_Android_22.04.2025_v1.0.0-release.tar.gz

can be used.

This tar file contains the binaries and libraries for the compiler clang20 and the files necessary to compile binaries and libraries for Android on an arm64 CPU from the Android NDK r29-beta1 compiled for Android on arm64 CPUs.

The tar file is an add-on for the tar file with the clang19 toolchain for Android on arm64 CPUs, but can also be used without the files from the tar archive with clang19 if the other files from the toolchain for clang19 are either not required or are provided by other methods.

The tar file with the clang19 toolchain is available here:

clang19_toolchain*tar.gz

(see here for the documentation for that tar file)


To use the clang20 in this tar archive, install and initialize the tar file with the clang19 and then copy the tar file with the clang20 to the phone and unpack it in the directory /data/local/tmp, e.g:

cd /data/local/tmp
tar -xf /sdcard/Download/clang20_for_Android_22.04.2025_v1.0.0-release.tar.gz


The clang20 files are then in the directory

/data/local/tmp/sysroot/usr/clang20


The binaries for clang20 are in the directory

/data/local/tmp/sysroot/usr/clang20/bin


The files from the Android NDK are in the directory

/data/local/tmp/sysroot/usr/ndk/r29-beta1

The sysroot from the Android NDK is in the directory

/data/local/tmp/sysroot/usr/ndk/r29-beta1/sysroot


Use the command

source /data/local/tmp/sysroot/bin/init_clang20_env

to init the environment for the clang20. This script defines all necessary environment variables (including the PATH variable) to use the clang20.

e.g.

source /data/local/tmp/sysroot/bin/init_clang20_env

ASUS_I006D:/ $ source /data/local/tmp/sysroot/bin/init_clang20_env

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

Using clang 20                                                                            
Using the NDK /data/local/tmp/sysroot/usr/ndk/r29-beta1                                    (environment variable NDK_DIR)
Using the sysroot directory /data/local/tmp/sysroot/usr/ndk/r29-beta1/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/sysroot/usr/clang20/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/develop/sysroot/usr/bin

LD_LIBRARY_PATH:     :/data/local/tmp/sysroot/usr/ndk/r29-beta1/sysroot/usr/lib/aarch64-linux-android:/data/local/tmp/sysroot/usr/clang20/lib

API is now:          31
NDK_DIR is now:      /data/local/tmp/sysroot/usr/ndk/r29-beta1

SYSROOT is now:      /data/local/tmp/sysroot/usr/ndk/r29-beta1/sysroot

CFLAGS are now:       -I/data/local/tmp/sysroot/usr/clang20/include -I/data/local/tmp/sysroot/usr/ndk/r29-beta1/include -I/data/local/tmp/sysroot/usr/ndk/r29-beta1/sysroot/usr/include -I/data/local/tmp/develop/sysroot/usr/include --sysroot=/data/local/tmp/sysroot/usr/ndk/r29-beta1/sysroot

CPPFLAGS are now:     -I/data/local/tmp/sysroot/usr/clang20/include -I/data/local/tmp/sysroot/usr/ndk/r29-beta1/include -I/data/local/tmp/sysroot/usr/ndk/r29-beta1/sysroot/usr/include -I/data/local/tmp/develop/sysroot/usr/include

CXXFLAGS are now:     -I/data/local/tmp/sysroot/usr/clang20/include -I/data/local/tmp/sysroot/usr/ndk/r29-beta1/include -I/data/local/tmp/sysroot/usr/ndk/r29-beta1/sysroot/usr/include -I/data/local/tmp/develop/sysroot/usr/include --target=aarch64-linux-android31

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

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

TMP is now:          /data/local/tmp
Checking the clang binary ...

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

ASUS_I006D:/ $

---

The script init_clang20_env executes the script

/data/local/tmp/local_init_clang20_env

if it exists (use the parameter "no_user" for the script init_clang20_env to disable the execution of that script)


Use the command

/data/local/tmp/sysroot/bin/init_clang20_env help

to print the usage help for the init script:

/data/local/tmp/sysroot/bin/init_clang20_env help
ASUS_I006D:/data/local/tmp $ /data/local/tmp/sysroot/bin/init_clang20_env help
       
Usage: . /data/local/tmp/sysroot/bin/init_clang20_env [-h|--help] [init] [no_user] [var=value] [examples]
 
init        - clear the used enviroment variables at script start
no_user     - do not execute /data/local/tmp/local_init_clang20_env
var=value   - set the environment variable "var" to "value" at start of the script
examples    - print compile examples


*************************************************************************************
 WARNING: The script /data/local/tmp/sysroot/bin/init_clang20_env must be sourced in
*************************************************************************************
ASUS_I006D:/data/local/tmp $



The tar archive also contains the source code for two simple C/C++ programs to test the compiler in the directory ./sysroot/usr/share/clang20:

ASUS_I006D:/data/local/tmp/ $ cd /data/local/tmp/sysroot/usr/share/clang20
ASUS_I006D:/data/local/tmp/sysroot/usr/share/clang20 $

ASUS_I006D:/data/local/tmp/sysroot/usr/share/clang20 $ clang ${CFLAGS} ${LDFLAGS} -o helloworld_in_c helloworld_in_c.c  && ./helloworld_in_c
Hello, World from a C program!
Compiled with Clang 20.0.0
ASUS_I006D:/data/local/tmp/sysroot/usr/share/clang20 $

ASUS_I006D:/data/local/tmp $ cd /data/local/tmp/sysroot/usr/share/clang20
ASUS_I006D:/data/local/tmp/sysroot/usr/share/clang20 $

ASUS_I006D:/data/local/tmp/sysroot/usr/share/clang20 $                                                                                                                                                              
ASUS_I006D:/data/local/tmp/sysroot/usr/share/clang20 $ clang++ ${CXXFLAGS} -lc++_shared ${LDFLAGS}  -o helloworld_in_c++ ./helloworld_in_c++.cpp && ./helloworld_in_c++
Hello, World from a C++ program!
Compiled with Clang 20.0.0
Compiler version: Clang 20.0.0git (https://android.googlesource.com/toolchain/llvm-project b718bcaf8c198c82f3021447d943401e3ab5bd54)
ASUS_I006D:/data/local/tmp/sysroot/usr/share/clang20 $


Source Code used to create the binaries


The repository with the source code for the clang is:

https://android.googlesource.com/toolchain/llvm-project

The source code was checked out in 04/2025.


To get the source for clang20 use these commands:

git clone https://android.googlesource.com/toolchain/llvm-project

cd llvm-project

git checkout llvm-r547379-release


See the file

./sysroot/usr/share/clang20/source/myconfigure_for_clang20

in the tar archive for the cmake options used to prepare the build process for the clang20.
The clang20 binaries were compiled on a machine running the Linux OS with the Cross Compiler from the Android NDK r27b.


The Android NDKs are available here:

https://developer.android.com/ndk/downloads



The files from the tar file are also avialable in a repository on github: 

https://github.com/bnsmb/clang20-for-Android/




History of this entry

23.04.2025

initial release





How to compile a C program for Android in Android using gcc



How to compile a C or C++ program for Android in Android with gcc without root access


URL: https://xdaforums.com/t/guide-how-to-compile-a-c-or-c-program-for-android-in-android-with-gcc-without-root-access.4790361/

How to compile a C or C++ program for Android in Android with gcc without root access

To compile C or C++ programs for Android using the gcc toolchain on Android, you can use the files from this GitHub repository:

https://github.com/AmanoTeam/android-gcc-cross/


The repository contains a gcc toolchain compiled for mostly all CPUs used in Android phones. As of 30.05.2026 the gcc version in the repository is 16.1.1.

There is also a very well-designed installation script for the gcc toolchain :

https://cdn.jsdelivr.net/gh/AmanoTeam/android-gcc-cross@master/tools/termux-install.sh


The script is written for running in a Termux session but with some minor modifications it can also be used in adb sessions:


The script uses parameter in the long format for commands such as rm, ln, etc. These options are not supported by the commands in most Android versions and must therefore be modified:

cp termux-install.sh gcc-install.sh
sed -i -e "s/--symbolic/-s/g" -e "s/--force/-f/g" -e "s/--recursive/-r/g" gcc-install.sh


The target directory for the gcc toolchain is hardcoded in the script:

ASUS_I006D:/data/local/tmp $ egrep "^declare pino_directory" gcc-install.sh                                                                                                                                  
declare pino_directory='/data/data/com.termux/files/usr/lib/android-gcc-cross'
ASUS_I006D:/data/local/tmp $

Change it to your need, e.g.:

ASUS_I006D:/data/local/tmp $ egrep "^declare pino_directory" gcc-install.sh                                                                                                                                       
declare pino_directory='/data/local/tmp/sysroot/usr/lib/android-gcc-cross'
ASUS_I006D:/data/local/tmp $


The target directory for the symbolic links for the binaries from the gcc toolchain is defined using the environment variable PREFIX in the script:

ASUS_I006D:/data/local/tmp $ grep "^declare bindir" gcc-install.sh                                                                                                                                                
declare bindir="${PREFIX}/bin/gcc-toolchain"
ASUS_I006D:/data/local/tmp $

Either modify that statement or set the environment variable PREFIX before starting the script


The script uses curl to download the tar file with the gcc toolchain. If there is no curl binary in the Android OS on the phone, download the curl binary for example from here (for arm64 CPUs):

http://bnsmb.de/files/public/Android/binaries_for_arm64/curl



Then you can execute the script to install the gcc toolchain :


export PREFIX=/data/local/tmp/sysroot

export HOME=/data/local/tmp/sysroot/home

mkdir -p ${PREFIX}/bin ${PREFIX}/usr/lib/ ${PREFIX}/home

( cd / && bash /data/local/tmp/gcc-install.sh )


Example

/data/local/tmp/gcc-install.sh
ASUS_I006D:/data/local/tmp $ export PREFIX=/data/local/tmp/sysroot
ASUS_I006D:/data/local/tmp $

ASUS_I006D:/data/local/tmp $ export HOME=/data/local/tmp/sysroot/home
ASUS_I006D:/data/local/tmp $

ASUS_I006D:/data/local/tmp $ mkdir -p ${PREFIX}/bin ${PREFIX}/usr/lib/ ${PREFIX}/home
ASUS_I006D:/data/local/tmp $

ASUS_I006D:/data/local/tmp $ ( cd / && bash /data/local/tmp/gcc-install.sh )
* ABI: aarch64
* Primary target: aarch64-unknown-linux-android
* Secondary target: armv7-unknown-linux-androideabi
* System version: 36
- Fetching archive from 'https://github.com/AmanoTeam/android-gcc-cross/releases/download/gcc-16/aarch64-unknown-linux-android.tar.xz' to '/data/local/tmp/gcc-toolchain.tar.xz'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  230M  100  230M    0     0  1475k      0  0:02:39  0:02:39 --:--:--  764k
- Unpacking tarball from '/data/local/tmp/gcc-toolchain.tar.xz' to '/data/local/tmp/sysroot/usr/lib/android-gcc-cross'
- Symlinking host tools to '/data/local/tmp/sysroot/bin/gcc-toolchain'
- Removing '/data/local/tmp/gcc-toolchain.tar.xz'
- Modifying '/data/local/tmp/sysroot/home/.bashrc'
- Adding custom DT_RUNPATH to GCC runtime libraries
- Installation finished!
ASUS_I006D:/data/local/tmp $
 




After the script finished, change the shebang in the scripts in the gcc toolchain :

NEW_SHELL="$( which bash )"
[ "${NEW_SHELL}"x = ""x ] && NEW_SHELL="$( which sh )"

sed -i -e "s#/data/data/com.termux/files/usr/bin/bash#${NEW_SHELL}#g" $( file ${PREFIX}/bin/gcc-toolchain/* | grep script | cut -f1 -d ":" )


sed -i -e "s#/bin/bash#${NEW_SHELL}#g" $( file ${PREFIX}/usr/lib/android-gcc-cross/bin/* | grep script | cut -f1 -d ":" )


Check, if the gcc binary works:

${PREFIX}/bin/gcc-toolchain/gcc --version

e.g.

ASUS_I006D:/data/local/tmp $ ${PREFIX}/bin/gcc-toolchain/gcc --version
aarch64-unknown-linux-android-gcc (GCC) 16.1.1 20260530
Copyright (C) 2026 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ASUS_I006D:/data/local/tmp $


Now you can compile C/C++ programs using the gcc toolchain:


Example

Note: This example assumes the gcc toolchain is installed in the directory /data/local/tmp/sysroot.


create a sample C program
cat  > /data/local/tmp/sysroot/helloworld_in_c.c   <<-\EOT
#include <stdio.h>

int main() {
    printf("Hello, World from a C program!\n");

#ifdef __clang__
    printf("Compiled with Clang %d.%d.%d\n", __clang_major__, __clang_minor__, __clang_patchlevel__);
#elif defined(__GNUC__)
    printf("Compiled with GCC %d.%d.%d\n", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
#else
    printf("Compiled with an unknown compiler\n");
#endif

    return 0;
}
EOT

---

create a sample C++ program
cat >/data/local/tmp/sysroot/helloworld_in_c++.cpp <<-\EOT

#include <iostream>  // include the input-output stream library

int main() {
    std::cout << "Hello, World from a C++ program!" << std::endl;  // output the message to the console


#ifdef __clang__
    std::cout << "Compiled with Clang "
              << __clang_major__ << "."
              << __clang_minor__ << "."
              << __clang_patchlevel__ << std::endl;
#elif defined(__GNUC__)
    std::cout << "Compiled with GCC "
              << __GNUC__ << "."
              << __GNUC_MINOR__ << "."
              << __GNUC_PATCHLEVEL__ << std::endl;
#else
    std::cout << "Compiled with an unknown compiler" << std::endl;
#endif

    std::cout << "Compiler version: " << __VERSION__ << std::endl;

   return 0;  // indicate successful completion of the program

}
EOT
 
----


Init the environment

PATH=/data/local/tmp/sysroot/bin/gcc-toolchain/:$PATH 

cd /data/local/tmp/sysroot


Compile & test the C program

gcc helloworld_in_c.c -o helloworld_in_c && ./helloworld_in_c


Compile & test the C++ program

g++ helloworld_in_c++.cpp -o helloworld_in_c++ && ./helloworld_in_c++



Example output

ASUS_I006D:/data/local/tmp/sysroot $ PATH=/data/local/tmp/sysroot/bin/gcc-toolchain/:$PATH 
ASUS_I006D:/data/local/tmp/sysroot $

ASUS_I006D:/data/local/tmp/sysroot $ cd /data/local/tmp/sysroot
ASUS_I006D:/data/local/tmp/sysroot $

ASUS_I006D:/data/local/tmp/sysroot $ gcc helloworld_in_c.c -o helloworld_in_c && ./helloworld_in_c
Hello, World from a C program!
Compiled with GCC 16.1.1
ASUS_I006D:/data/local/tmp/sysroot $

ASUS_I006D:/data/local/tmp/sysroot $ g++ helloworld_in_c++.cpp -o helloworld_in_c++ && ./helloworld_in_c++
Hello, World from a C++ program!
Compiled with GCC 16.1.1
Compiler version: 16.1.1 20260529
ASUS_I006D:/data/local/tmp/sysroot $

  ----


Notes

The gcc toolchain contains the minimal necessary files to compile and link files with gcc or g++. The Android NDK is NOT required.

The executables in the gcc toolchain are:

ASUS_I006D:/ $ ls /data/local/tmp/sysroot/bin/gcc-toolchain/ | grep -v unknown
addr2line
ar
as
c++
c++filt
cc
cpp
dwp
elfedit
g++
gcc
gcc-ar
gcc-nm
gcc-ranlib
gcov
gcov-dump
gcov-tool
gprof
ld
ld.bfd
ld.gold
lto-dump
nm
objcopy
objdump
ranlib
readelf
size
strings
strip
ASUS_I006D:/ $


Other necessary tools for compiling programs, such as make, are not part of this gcc toolchain. You can download the missing binaries, for example from the GitHub repository with the clang19 toolchain:

https://github.com/bnsmb/clang19_toolchain_for_android


Notes

The gcc ignores include directories specified with the parameter -I whose names are already used for directories with header files in the build-in NDK, such as sysroot/usr/include.

You can bypass this check by renaming the directory to something else (e.g., /develop/sysroot/include or simply /develop/include), and gcc should then accept it.

Example:

ASUS_I006D:/ $ echo | gcc -I/data/local/tmp/develop/sysroot/usr/include -E -Wp,-v - 2>&1 | grep -A 20 "search starts"
#include "..." search starts here:
#include <...> search starts here:
 /data/local/tmp/sysroot/usr/lib/android-gcc-cross/lib/gcc/aarch64-unknown-linux-android/16/include
 /data/local/tmp/sysroot/usr/lib/android-gcc-cross/aarch64-unknown-linux-android36/include
 /data/local/tmp/sysroot/usr/lib/android-gcc-cross/aarch64-unknown-linux-android36/include/aarch64-unknown-linux-android
End of search list.
# 0 "<stdin>"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "<stdin>"
ASUS_I006D:/ $

->  the gcc ignores the directory /data/local/tmp/develop/sysroot/usr/include 


[shell@localhost /data/local/tmp/develop/clang19_dev_backup/gcc/binutils-2.43]$ echo | gcc -I/data/local/tmp/develop/dev/usr/include -E -Wp,-v - 2>&1 | grep -A 20 "search starts"
#include "..." search starts here:
#include <...> search starts here:
 /data/local/tmp/develop/dev/usr/include
 /data/local/tmp/gcc_sysroot/usr/lib/android-gcc-cross/lib/gcc/aarch64-unknown-linux-android/16/include
 /data/local/tmp/gcc_sysroot/usr/lib/android-gcc-cross/aarch64-unknown-linux-android36/include
 /data/local/tmp/gcc_sysroot/usr/lib/android-gcc-cross/aarch64-unknown-linux-android36/include/aarch64-unknown-linux-android
End of search list.
# 0 "<stdin>"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "<stdin>"

->  the gcc uses the directory /data/local/tmp/develop/dev/usr/include 



The installation script for the gcc toolchains automatically adjusts the path configuration in the executable files to match the current installation. Therefore, you do not need to set LD_LIBRARY_PATH. You also do not need to specify LDFLAGS or CFLAGS for the directories containing include files and libraries in the gcc toolchain.
The downside is that you cannot move the gcc toolchain to a different directory. To move the gcc toolchain to a different directory, you must reinstall it (or modify the executables manually).



Trouble Shooting

The error message

curl: (35) Recv failure: Connection reset by peer

while the install script is running can be ignored.


If the script fails with an error message like this:

job-working-directory: error retrieving current directory: getcwd: cannot access parent directories: Math result not representable

or this:

shell-init: error retrieving current directory: getcwd: cannot access parent directories: Math result not representable

use sh instead of bash for the shebangs in the scripts

Or use this bash binary:

http://bnsmb.de/files/public/Android/binaries_for_arm64/bash


Notes

To add the gcc 16.1.1 to the clang19 toolchain 1.7 or older, download the tar file

http://bnsmb.de/files/public/Android/tar_files/gcc16_1_1_for_clang19_toolchain.tar.gz

copy it to the phone, and unpack it in the directory

/data/local/tmp

The tar file contains all necessary files to compile source files with gcc/g++ and also updated versions of the scripts

bin/init_clang_env

and

compile_examples.sh




History of this entry

03.06.2026

added the instructions to add the gcc 16.x to the clang19 toolchain


01.06.2026

added the information about the handling of directories with include files


31.05.2026

initial release





How to compile a C program for Android in Android using a Magisk module with gcc


URL: https://xdaforums.com/t/guide-compiling-c-programs-in-android-using-gcc.4695529/


How to compile a C program for Android in Android using a Magisk module with gcc


There is a Magisk Module with a GCC toolchain for Android that can be used to compile C programs in Android sessions: https://github.com/Googlers-Repo/gcc/.  

I've tested it and IMHO the GCC toolchain is very useful for compiling some of the good old Unix programs for the Android OS without having to deal with cross-compiling issues on the PC.

Find below some hints for using that GCC toolchain to compile C programs in Android.


The Magisk Module can be installed using the instructions in the repository https://github.com/Googlers-Repo/gcc/, via the Magisk Module Repo Loader, the Magisk GUI, or the magisk binary.

The Magisk Module requires the Magisk Module for mksh and adds the directories with the tools from the GCC toolchain to the variable PATH via mksh profile:

shell@localhost:/data/mkuser/home/shell
└─$ cat /system/etc/mkshrc.d/gcc_on_android.sh                                                                          
export PATH="$PATH:/system/usr/share/gcc/bin:/system/usr/share/gcc/aarch64-linux-android/bin:/system/usr/share/gcc/libexec/gcc/aarch64-linux-android/10.2.0"┌shell@localhost:/data/mkuser/home/shell
└─$
┌shell@localhost:/data/mkuser/home/shell
└─$ echo $PATH                                                                                                          
/data/mkuser/usr/bin:/data/mkuser/home/shell/.local/bin:/system/bin:/sbin:/vendor/bin:/system/sbin:/system/xbin:/system/product/bin:/system/usr/share/bin-get/bin:/system/system_ext/bin:/system/usr/share/gcc/bin:/system/usr/share/gcc/aarch64-linux-android/bin:/system/usr/share/gcc/libexec/gcc/aarch64-linux-android/10.2.0
┌shell@localhost:/data/mkuser/home/shell
└─$
┌shell@localhost:/data/mkuser/home/shell
└─$ gcc --version                                                                                                       
aarch64-linux-android-gcc (GCC) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

┌shell@localhost:/data/mkuser/home/shell
└─$
┌shell@localhost:/data/local/tmp/develop
└─$ gcc -v                                                                                                                           
Using built-in specs.
COLLECT_GCC=aarch64-linux-android-gcc
Target: aarch64-linux-android
Configured with: ../configure --host=aarch64-linux-gnu --target=aarch64-linux-android --enable-static --disable-shared --enable-languages=c,c++ --enable-initfini-array --disable-lto --disable-libquadmath --disable-multilib --disable-libgomp --disable-libmudflap --enable-target-optspace --enable-threads --disable-libatomic --disable-tls --disable-nls --disable-sjlj-exceptions --disable-libstdc++-v3 --disable-libsanitizer --disable-plugins --disable-libgcc --disable-libssp --disable-docs --disable-libitm --with-gnu-as --with-gnu-ld --prefix=/home/n0n3m4/Desktop/C4droid/prog/c4droid/OutDir --with-mpc=/home/n0n3m4/Desktop/C4droid/prog/c4droid/mpc --with-mpfr=/home/n0n3m4/Desktop/C4droid/prog/c4droid/mpfr --with-gmp=/home/n0n3m4/Desktop/C4droid/prog/c4droid/gmp
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.2.0 (GCC)
┌shell@localhost:/data/local/tmp/develop
└─$


The libraries in the GCC toolchain are from the Android API version 21:

┌shell@localhost:/data/local/tmp/develop
└─$ file bvi-1.4.2/bvi                                                                                                               
bvi-1.4.2/bvi: ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), for Android 21, built by NDK r17c (4988734), not stripped
┌shell@localhost:/data/local/tmp/develop
└─$

Note:

If a newer Android API is required, use the other gcc compiler instead -- see How to compile a C or C++ program for Android in Android with gcc without root access


The directory tree with the standard include files and libraries in the GCC toolchain is

/system/usr/share/gcc/aarch64-linux-android


To compile a C program using the GCC toolchain these flags for the compiler and linker are necessary:

export LDFLAGS="-pie"
export CFLAGS="-fPIE"


I also recommend to create a separate sysroot for the compiled binaries and libraries :

mkdir -p /data/local/tmp/develop/sysroot/ && \
cd
/data/local/tmp/develop/sysroot/ && \
mkdir -p usr usr/bin usr/sbin usr/include usr/lib usr/lib64 usr/share && \
{
ln -s usr/lib ./lib
ln -s usr/lib64 ./lib64
ln -s usr/bin ./bin
ln -s usr/sbin ./sbin
}


Now you can use the configure script like this to create the make files for compiling a Unix tool:

export SYSROOT=/system/usr/share/gcc/aarch64-linux-android

export TARGET_ROOT=
/data/local/tmp/develop/sysroot

export LDFLAGS="-pie  -L${
TARGET_ROOT}/usr/lib"
export  CFLAGS="-fPIE -I${TARGET_ROOT}/usr/include"

export LD_LIBRARY_PATH=${
LD_LIBRARY_PATH}:${TARGET_ROOT}/usr/lib

export PATH=${TARGET_ROOT}/usr/bin:${PATH}
 

./configure --prefix ${TARGET_ROOT}


use

make

to start the compile process


If necessary, add the parameter for the sysroot. Example to compile nmon:

# create a dummy fstab.h file for nmon
#
touch $TARGET_ROOT/usr/include/fstab.h

gcc --sysroot=${SYSROOT}  ${CFLAGS} ${LDFLAGS} lmon16q.c -o nmon  -Wno-format-security -Wno-format -lncurses -O3 -Wall -D JFS -D GETUSER -D LARGEMEM -g


Example output
┌shell@localhost:/data/local/tmp/develop
└─$ gcc --sysroot=${SYSROOT}  ${CFLAGS} ${LDFLAGS} lmon16q.c -o nmon  -Wno-format-security -Wno-format -lncurses -O3 -Wall -D JFS -D GETUSER -D LARGEMEM -g
┌shell@localhost:/data/local/tmp/develop
└─$ ls -l nmon
-rwxrwxrwx 1 shell shell 751512 2024-09-26 17:55 nmon
┌shell@localhost:/data/local/tmp/develop
└─$
┌shell@localhost:/data/local/tmp/develop
└─$ file nmon
nmon: ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), for Android 21, built by NDK r17c (4988734), not stripped
┌shell@localhost:/data/local/tmp/develop
└─$
┌shell@localhost:/data/local/tmp/develop
└─$ ldd $PWD/nmon
    linux-vdso.so.1 => [vdso] (0x7612a8e000)
    libm.so => /apex/com.android.runtime/lib64/bionic/libm.so (0x760db03000)
    libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x760c854000)
    libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x760db79000)
┌shell@localhost:/data/local/tmp/develop
└─$      
┌shell@localhost:/data/local/tmp/develop
└─$ ./nmon --help
nmon: invalid option -- -
Hint for nmon version 16q
    Full Help Info : nmon -h

    On-screen Stats: nmon
    Data Collection: nmon -f [-s <seconds>] [-c <count>] [-t|-T]
    Capacity Plan  : nmon -x
Interactive-Mode:
    Read the Welcome screen & at any time type: "h" for more help
    Type "q" to exit nmon

For Data-Collect-Mode
    -f            Must be the first option on the line (switches off interactive mode)
                  Saves data to a CSV Spreadsheet format .nmon file in then local directory
                  Note: -f sets a defaults -s300 -c288    which you can then modify
    Further Data Collection Options:
    -s <seconds>  time between data snapshots
    -c <count>    of snapshots before exiting
    -t            Includes Top Processes stats (-T also collects command arguments)
    -x            Capacity Planning=15 min snapshots for 1 day. (nmon -ft -s 900 -c 96)
---- End of Hints
┌shell@localhost:/data/local/tmp/develop
└─$




For source code trees that are prepared for the use of configure but do not have a configure script (-> the file configure.ac exists but not the file configure), use the autoconf tool to create the configure script; the command to create the configure script is:

autoconf -fi


If autoconf ends with an error like this:

shell@localhost:/data/local/tmp/develop/unrar-free
└─$  autoconf -fi
configure.ac:6: error: possibly undefined macro: AM_INIT_AUTOMAKE
      If this token and others are legitimate, please use m4_pattern_allow.
      See the Autoconf documentation.
┌shell@localhost:/data/local/tmp/develop/unrar-free
└─$

execute the tool aclocal once and restart autoconf

aclocal
autoconf -fi


A Magisk Module with autoconf (including the necessary tools for autoconf) is available here: autoconf_2.72.zip 



Trouble Shooting


If the installation of the Magisk Module with gcc fails with an error message about a missing mkshrc, such as:

mkshrc is missing; please install it to use this module.

but the Magisk Module mkshrc is already installed, manually create the directory checked by the installation script in the Magisk Module with gcc 

su - -c mkdir /debug_ramdisk/.magisk/modules/mkshrc

and restart the installation




On some ROMs the install script for the Magisk Module with the GCC toolchain does not configure the execute permission for the wrapper scripts used in the Magisk Module. Therefor check the permissions for the scripts after installing the Magisk Module and correct them if necessary:

┌root@localhost:/
└─# ls -l /data/adb/modules_update/gcc_on_android/system/usr/share/gcc/aarch64-linux-android/bin
total 14432
-rwxr-xr-x 1 root shell  835784 2024-09-26 15:32 ar
-rwxr-xr-x 1 root shell 1393248 2024-09-26 15:32 as
-rw-r--r-- 1 root root       48 2024-09-26 15:32 cc
-rwxr-xr-x 1 root shell 8082896 2024-09-26 15:32 cmake
-rw-r--r-- 1 root root       48 2024-09-26 15:32 g++
-rw-r--r-- 1 root root       48 2024-09-26 15:32 gcc
-rwxr-xr-x 1 root shell 1807376 2024-09-26 15:32 ld
-rwxr-xr-x 1 root shell  824400 2024-09-26 15:32 nm
-rwxr-xr-x 1 root shell  835784 2024-09-26 15:32 ranlib
-rwxr-xr-x 1 root shell  956800 2024-09-26 15:32 strip
┌root@localhost:/
└─# chmod 755 /data/adb/modules_update/gcc_on_android/system/usr/share/gcc/aarch64-linux-android/bin/*
┌root@localhost:/
└─# ls -l /data/adb/modules_update/gcc_on_android/system/usr/share/gcc/aarch64-linux-android/bin
total 14432
-rwxr-xr-x 1 root shell  835784 2024-09-26 15:32 ar
-rwxr-xr-x 1 root shell 1393248 2024-09-26 15:32 as
-rwxr-xr-x 1 root root       48 2024-09-26 15:32 cc
-rwxr-xr-x 1 root shell 8082896 2024-09-26 15:32 cmake
-rwxr-xr-x 1 root root       48 2024-09-26 15:32 g++
-rwxr-xr-x 1 root root       48 2024-09-26 15:32 gcc
-rwxr-xr-x 1 root shell 1807376 2024-09-26 15:32 ld
-rwxr-xr-x 1 root shell  824400 2024-09-26 15:32 nm
-rwxr-xr-x 1 root shell  835784 2024-09-26 15:32 ranlib
-rwxr-xr-x 1 root shell  956800 2024-09-26 15:32 strip
┌root@localhost:/
└─#


The gcc in this GCC toolchain is version gcc 10.2 and the libraries in the GCC toolchain come from the Android API version 21, which are both quite old.

Some of the functions and variables used in current versions of some Unix programs are missing in the libc.so from the API version 21 in the GCC toolchain.

If you get an error like this:

lib/libbison.a(libbison_a-close-stream.o): In function `close_stream':
close-stream.c:(.text+0x10): undefined reference to `__fpending'

use aunt Google to check if the missing symbol is defined in the libc.so. If yes, use the tool nm to check if that symbol is defined in the libc.so in the GCC toolchain:

shell@localhost:/data/local/tmp/develop/work/bison-3.8
└─$ nm /system/usr/share/gcc/aarch64-linux-android/lib/libc.so | grep __fpending                                                                                                  
┌shell@localhost:/data/local/tmp/develop/work/bison-3.8
└─$ 


Instead of checking with Google you can also check the libc of a current Linux version for the PC:

[aarch64-linux-android] [ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/ModuleSrc/python_3.10.4 ] $ nm /lib64/libc.so.6 | grep __fpending
000000000008c610 T __fpending
[aarch64-linux-android] [ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/ModuleSrc/python_3.10.4 ] $



Details for the symbol __fpending

fyi: The symbol __fpending from the example above is defined in the libc.so from the API version 23 and newer:

[aarch64-linux-android] [ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib ] $ for i in ./aarch64-linux-android/*/libc.so ; do echo "** $i:" ;  nm $i | grep  __fpending ; done
** ./aarch64-linux-android/21/libc.so:
** ./aarch64-linux-android/22/libc.so:
** ./aarch64-linux-android/23/libc.so:
00000000000180c8 T __fpending
** ./aarch64-linux-android/24/libc.so:
00000000000190c8 T __fpending
** ./aarch64-linux-android/26/libc.so:
000000000001a0c8 T __fpending
** ./aarch64-linux-android/27/libc.so:
000000000001a0c8 T __fpending
** ./aarch64-linux-android/28/libc.so:
000000000001c0c8 T __fpending
** ./aarch64-linux-android/29/libc.so:
000000000001c0c8 T __fpending
** ./aarch64-linux-android/30/libc.so:
000000000001d0c8 T __fpending
** ./aarch64-linux-android/31/libc.so:
000000000001e0c8 T __fpending
** ./aarch64-linux-android/32/libc.so:
000000000001e0c8 T __fpending
** ./aarch64-linux-android/33/libc.so:
000000000001e0c8 T __fpending
[aarch64-linux-android] [ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib ] $




If the configure script to create the Makefile for a tool fails with an error message about the missing -fPIE option, the configure script most likely uses gcc to compile and link a test program using only the $CFLAGS. In this case, simply add the parameter for the linker to the CFLAGS, e.g. with

export CFLAGS="-fPIE -pie”

and restart the configure script.




if the linker complains about an "undefined reference to main" while creating a library, remove the option "-pie", example:

┌root@localhost:/data/local/tmp/develop/zlib-1.3.1
└─# gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map -fPIE -I/data/local/tmp/develop/sysroot/usr/include -fPIC -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -o libz.so.1.3.1 \
>    adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo \
>    -lc -pie -L/data/local/tmp/develop/sysroot/usr/lib
/system/usr/share/gcc/bin/../lib/gcc/aarch64-linux-android/10.2.0/../../../../aarch64-linux-android/lib/crtbegin_dynamic.o: In function `_start_main':
crtbegin.c:(.text+0x20): undefined reference to `main'
crtbegin.c:(.text+0x4c): undefined reference to `main'
collect2: error: ld returned 1 exit status
┌root@localhost:/data/local/tmp/develop/zlib-1.3.1
└─#

┌root@localhost:/data/local/tmp/develop/zlib-1.3.1
└─# gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map -fPIE -I/data/local/tmp/develop/sysroot/usr/include -fPIC -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -o libz.so.1.3.1 \
>    adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo \
>    -lc -L/data/local/tmp/develop/sysroot/usr/lib
┌root@localhost:/data/local/tmp/develop/zlib-1.3.1
└─#                                                                                                                                                                                                                                                      

┌root@localhost:/data/local/tmp/develop/zlib-1.3.1
└─# ls -l libz.so.1.3.1                                                                                                                                                                                                                          
-rwxr-xr-x 1 root root 159856 2024-10-01 15:13 libz.so.1.3.1
┌root@localhost:/data/local/tmp/develop/zlib-1.3.1
└─#


Alternativley, you can add the option -nostartfiles and ignore the warning, example:

┌root@localhost:/data/local/tmp/develop/zlib-1.3.1
└─# ls -l libz.so.1.3.1                                                                                                                                                                                                                          
ls: libz.so.1.3.1: No such file or directory
┌root@localhost:/data/local/tmp/develop/zlib-1.3.1
└─# 
┌root@localhost:/data/local/tmp/develop/zlib-1.3.1
└─# cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map -fPIE -I/data/local/tmp/develop/sysroot/usr/include -fPIC -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -o libz.so.1.3.1 \
>    adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo \
>    -lc -pie -L/data/local/tmp/develop/sysroot/usr/lib -nostartfiles
/system/usr/share/gcc/bin/../lib/gcc/aarch64-linux-android/10.2.0/../../../../aarch64-linux-android/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000000e90
┌root@localhost:/data/local/tmp/develop/zlib-1.3.1
└─#
┌root@localhost:/data/local/tmp/develop/zlib-1.3.1
└─# ls -l libz.so.1.3.1                                                                                                                                                                                                                                   <
-rwxr-xr-x 1 root root 154856 2024-10-01 15:20 libz.so.1.3.1
┌root@localhost:/data/local/tmp/develop/zlib-1.3.1
└─#


see also Troubleshooting some common problems for compiling programs for Android for hints to fix common compile errors





Notes

These instructions were created using the version 1.0.2 of the GCC toolchain.

As of 28.09.2024 I successfully compiled these tools and libraries with the GCC toolchain:

┌root@localhost:/data/local/tmp/develop
└─# date                                                                                                                                                          
Sat Sep 28 11:32:49 CEST 2024
┌root@localhost:/data/local/tmp/develop
└─#

┌root@localhost:/data/local/tmp/develop
└─# ls done
bgrep         flex-2.6.4     json-c-0.17  libexpat       libtasn1-4.19.0   libuv        nettle-3.10  pcre2           zstd
brotli-1.0.9  gmp-6.3.0      libconfuse   libgdbm        libtool-2.5.3     libxml2      nghttp2      pigz-2.8
bvi-1.4.2     inetutils-2.5  libevent     libiconv-1.17  libunistring-1.2  ncurses-6.3  nmon         readline-8.1.2
┌root@localhost:/data/local/tmp/develop
└─#                                                                                                                                                               



A Magisk module with a git binary for Android is available here: https://github.com/henriknelson/git-magisk-module
A Magisk module with a newer git version is available here: http://bnsmb.de/files/public/Android/MagiskModules/.   

see also Compiling C programs in Android in Termux for instructions to compile C programs in Termux sessions on the phone.

see also the Documentation for the Magisk Module with clang19 and the NDK r27b

see How to install a Toolchain for clang on phones without root access for how to install a clang toolchain as non-root user on an Android phone

see also How to compile a C or C++ program for Android in Android with gcc without root access



History of this entry

02.10.2024

added infos how to fix the error ""undefined reference to main" while creating a library
added infos about how to create the configure script using autoconf

29.09.2024

initial release






How to compile a C program for Android in Android in Termux


URL: https://xdaforums.com/t/how-to-compile-c-programs-in-android.4683687/


How to compile a C program in Android in Termux


The easiest way to compile C or C++ programs on Android is to install Termux on the phone.

Termux is basically a normal Linux environment that runs on the phone and compiling programs in Termux is more or less just like compiling in Linux on the PC (see below for some links with further infos about Termux).

To compile an existing Linux program the standard Linux tools like ./configure and make can be used in a Termux session. If a program complains about a missing library or tool just install it using

pkg install <packagename>


Example ./configure command to create the config files for building a Linux binary in a Termux session:

./configure     --prefix=/data/data/com.termux/files CFLAGS="-Wno-implicit-function-declaration  -Wno-int-conversion"

To create a binary that should run in an adb session and not in a Termux session add the parameters

--prefix=/data/local/tmp --datarootdir=/data/local/tmp

to the configure command (note that the Termux user can not access the directory /data/local/tmp without changing the permissions).

In principle, most Termux executables can also be used in an adb session. However, the user shell used in an adb session may not access the files in the directories used for Termux. In an adb session, root access is required to access the Termux files. Note that files created by the root user (implicitly or explicitly) in the directories used by Termux can no longer be used by the Termux user. Therefore, access to Termux files in an adb session should be avoided. Instead, copy the required files from the Termux directories to a directory available to the user shell (e.g. /data/local/tmp; but be aware that the directory /data/data/com.termux is hardcoded in some of the executables and therefor the executables will not work without access to that directory tree).

(see How to compile Perl for Android for an example)


Compiling programs for Android using Termux is easy doing but IMHO it's not fun to do this using the virtual keyboard of the phone (at least on my Zenfone 8 ...)
(A tool like scrcpy can be used to mirror the screen of the phone to the PC but this is still only a workaround)


Fortunately Termux contains an sshd and supports access via ssh.

For details how to configure access to Termux via ssh see here:

https://glow.li/posts/run-an-ssh-server-on-your-android-with-termux/

for details about how to configure access to Termux via adb see here (see access via adb is also using the sshd from Termux)

https://glow.li/posts/access-termux-via-usb/


To automatically start the sshd from Termux after opening the Termux App on the phone create a .profile like this:

cat /data/data/com.termux/files/home/.profile
exec >/data/data/com.termux/files/home/ssh_start.log 2>&1

CUR_USER=$( id -u -n )
ps  -ef | grep "^${CUR_USER}"  | grep -v grep  |  grep sshd >/dev/null
if [ $? -ne 0 ] ; then
    echo "Starting the sshd ..."
    sshd
    ps -ef | grep sshd
else
    echo "sshd already running"
fi
 


To start the sshd from Termux automatically after the reboot of the phone create a Magisk start script to start the Termux App:

cat /data/adb/service.d/start_sshd_from_termux
if ! tty -s ; then
  exec >"/data/cache/${0##*/}.log" 2>&1
fi

TIMEOUT=60
i=0

echo "Waiting up to ${TIMEOUT} seconds for /data/data/com.termux  ..."
while [ $i -lt ${TIMEOUT} ] ; do
  ls -ld /data/data/com.termux 2>/dev/null && break
  sleep 1
  let  i=i+1
  printf "."
done
printf "\n"
echo "Wait time: $i seconds "

set -x
ls -lZ /data/data/com.termux

#
# start the Termux App to init the environment

  am start com.termux/.app.TermuxActivity

# the sshd must be started from within the Termux app -> add the start command for the sshd to the file ~/.profile for the Termux User
#

# check that the sshd is running
sleep 3
ps -ef | grep sshd


Note:


Starting the Termux sshd from outside of the Termux app works also but only with an unusable, crippled environment in the ssh sessions.


Using both scripts the sshd from Termux starts automatically after every boot of the phone ; to access the phone via ssh use this command

ssh -p 8022 <IP_of_the_phone>

Example:

[ OmniRom 14 Dev - xtrnaw7@t15g ~ ] $ ssh -p 8022 192.168.1.148 "uname -a ; id"
Linux localhost 5.4.147-Omni-qgki-perf-gf532250e9298 #1 SMP PREEMPT Thu Jul 25 17:09:09 UTC 2024 aarch64 Android
uid=10149(u0_a149) gid=10149(u0_a149) groups=10149(u0_a149),3003(inet),9997(everybody),20149(u0_a149_cache),50149(all_a149)
[ OmniRom 14 Dev - xtrnaw7@t15g ~ ] $




Notes

I just found out after implementing the method to automatically start the sshd from Termux described above , that the start of the sshd from Termux can also be configured via Termux services and Termux Boot - see :

https://www.reddit.com/r/termux/comments/12fp1xc/start_sshd_process_from_bashrc_or_zshrc_on_termux/
https://wiki.termux.com/wiki/Termux-services
https://wiki.termux.com/wiki/Termux:Boot


Termux is available at F-Droid: https://f-droid.org/packages/com.termux/.
Termux is also available in the Playstore but I recommend the version from F-Droid (but you should consider supporting the developer -- see https://termux.dev/en/donate)

The homepage for Termux is https://termux.dev/en/

There is also a Wiki with documentation for Termux: https://wiki.termux.com/

See here for instructions to build new binaries for Termux:  https://github.com/termux/termux-packages

repo for the Termux app: https://github.com/termux/termux-app

Termux uses these directories on the phone:


Directory
Contents
Comment
/data/data/com.termux/files
base directory for the files used by Termux

/data/data/com.termux/files/usr
binaries, config files, etc:

ASUS_I006D:/ # ls /data/data/com.termux/files/usr/
bin  etc  include  lib  libexec  share  tmp  var
ASUS_I006D:/



/data/data/com.termux/files/home/
writable home directory for Termux



see also the Documentation for the Magisk Module with clang19 and the NDK r27b

see Troubleshooting some common problems for compiling programs for Android for hints to fix common compile errors

see How to install a Toolchain for clang on phones without root access for how to install a clang toolchain as non-root user on an Android phone

 

History of this entry

27.07.2024

added startup script examples to automatically start the Termux sshd 

25.07.2024

initial release





General hints



A directory tree with pre-compiled libraries and include files for Android on arm64 CPUs can be downloaded to the phone using the following commands, provided that the clang19 toolchain is installed on the phone:

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

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


For libraries required by an executable that are not part of the Android NDK, I recommend creating an additional sysroot environment, for example::

mkdir -p /data/develop/android/android_root
mkdir -p /data/develop/android/android_root/usr
mkdir -p /data/develop/android/android_root/usr/bin
mkdir -p /data/develop/android/android_root/usr/sbin
mkdir -p /data/develop/android/android_root/usr/lib
mkdir -p /data/develop/android/android_root/usr/include
mkdir -p /data/develop/android/android_root/usr/man

ln -s ./usr/bin /data/develop/android/android_root/bin
ln -s ./usr/lib /data/develop/android/android_root/lib
ln -s ./usr/sbin /data/develop/android/android_root/sbin


Then use the configure option --prefix=/data/develop/android/android_root/usr to compile and "install" the necessary libraries.

To use the include files and libaries from that sysroot environment to build executables for Android, use the additional compiler option

CFLAGS=-I/data/develop/android/android_root/usr/include

and the additional linker option

LDFLAGS=-L/data/develop/android/android_root/usr/lib


On the phone, the directories for the additional include files and libraries can be created in the directory, for example, /data/local/tmp/develop/sysroot.


It's recommended to check if there are patches for a Unix program in the Termux repository before starting the configure or make for the program.

The patches for the various Unix tools and programs in Termux are available here:

https://github.com/termux/termux-packages/tree/master/packages/


A l lot of make files support testing the compiled binaries using a command like "make test" or similar.


In case of an error it's recommended to check the page Common problems when compiling a C/C++ source file for Android and how to fix them for hints to fix common compile errors




How to create dynamically linked binaries for Android using C or C++


URL: https://xdaforums.com/t/guide-how-to-create-a-dynamically-linked-binary-for-android-using-c-or-c.4708356/

 
How to create dynamically linked binaries for Android using C or C++

Binary files for Android that are created with a C or C++ compiler can be linked either statically or dynamically. Both methods have advantages and disadvantages.


A small digression
Android is “only” Linux, so in the end it is a Unix derivative.

In Unix, executables can be linked either statically or dynamically. Normally, only dynamically linked executables are used in Unix (with a few exceptions). The reason is a basic principle of Unix: Each program and library does only one task - but it does it as well as possible. For example, there is a standard Unix library for evaluating regular expressions. If I now use regular expressions in a program, I do not write the routines for processing regular expressions myself, but use the standard Unix library for regular expressions.
If there is then a fix or an extension for the routines for Regular Expressions, only the library for regular expressions has to be exchanged and all programs that use regular expressions are automatically “updated”.

In Android, however, this can only be done to a limited extent for additionally installed binaries:

The standard directory for libraries in Android (/system/lib64 for arm64 CPUs) is now on a read-only mounted file system so no new libraries can be added here without tools such as Magisk. And unfortunately, replacing a library in /system/lib64 in Android can cause parts of Android or the Android OS to stop working.

Therefore, additional or updated libraries in Android should be in a separate directory and the executables that use them must know where they are (e.g. by setting the environment variable LD_LIBRARY_PATH). This is feasible, but actually very unattractive.



A statically linked binary file does not require any library and can, in principle, run on any Android version. Unfortunately, some statically linked binaries do not work at all on Android - they simply crash. And statically linked binaries cannot use hostname resolution on Android - for example, a statically linked wget2 binary can only use IP addresses, but not hostnames. And statically linked binaries are larger, but that should not be a problem anymore nowadays.

Update 06.06.2026

Another drawback of statically linked executables is that they cannot load shared library files. As a result, programs (such as certain interpreters) that reload dynamically linked libraries as needed during execution will only work partially if they are compiled as statically linked executables.


These restrictions do not apply to dynamically linked executables. However, dynamically linked executables cannot be executed without the required libraries. You must therefore always ensure that the libraries for using these executables are also installed and available for the OS. And some executables do not work with the libraries that are part of the Android operating system (e.g.some executables do not work with Android's ssl libraries).


To work around these limitations, it makes sense to create dynamically linked executables that contain all non-standard libraries and only require the standard libraries of the Android operating system, e.g:

ASUS_I006D:/ $ ldd /system/bin/wget2
    linux-vdso.so.1 => [vdso] (0x73d1ccc000)
    libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x73ca68e000)
    libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x73ca6ed000)
ASUS_I006D:/ $

The libraries used by this wget2 binary are standard Android libraries available in every Android OS.


Unfortunately, the configure scripts in the source code for most existing Unix binaries do not natively support the creation of this type of dynamically linked binaries - they create either makefiles for statically linked binaries or makefiles for dynamically linked binaries.

But with a few small manual tasks, creating this type of dynamically linked binary is quite easy

Example:

First setup your build environment to create dynamically linked binaries and create the Makefile for a dynamically linked binary (using the configure script for the binary, for example).

Then create the binary using make with the parameter V=1 (the parameter V=1 make sure that make prints all executed commands)

e.g. the messages from make for creating the binary bvi are:

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/bvi-1.4.2 ] $ make V=1 2>&1 | tee /var/tmp/make.log
/data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang --sysroot /data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot  -s -pie -L/data/develop/android/sysroot/usr/lib  -L/data/develop/android/sysroot/usr//lib -o bvi bvi.o comm.o set.o re.o io.o edit.o recomp.o -lncurses

#### build completed successfully  ####

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/bvi-1.4.2 ] $


Note:

When creating binaries with make, there are usually many more messages; the important message in the output of make for the instructions in this HowTo is the command to link the binary. To find this command, search for “ -o <binary name>” in the messages printed by make; in this example “-o bvi” (this is the command to link the binary).

Now check the command to link the binary for “-l” options: the values for the "-l" options specify the libraries required for the binary you have just created.

In the example above, there is only one "-l" option in the command

-lncurses

the value for the "-l" option is the name of the library to be used without the prefix “lib” and without the extension “.so”. In this example, the required library for the binary file is therefore libncurses.so

To create a binary file that no longer requires this library, we need the static version of this library: This is the file <library name>.a; in this example: libncurses.a 

If the static version of the library does not yet exist, create it.

These steps must be performed for each of the libraries required for the binary, except for the standard libraries in the Android OS, e.g. -ldl (= libdl.so is fine; this is the standard library /system/lib64/libdl.so)


Then recreate the binary using the static libraries instead of the dynamic libraries:

/data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang --sysroot /data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot  -s -pie -L/data/develop/android/sysroot/usr/lib  -L/data/develop/android/sysroot/usr//lib -o bvi bvi.o comm.o set.o re.o io.o edit.o recomp.o /data/develop/android/sysroot/usr/lib/libncurses.a

(In my environment the static library for ncurses is /data/develop/android/sysroot/usr/lib/libncurses.a)


Example:

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/bvi-1.4.2 ] $ /data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang --sysroot /data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot  -s -pie -L/data/develop/android/sysroot/usr/lib  -L/data/develop/android/sysroot/usr//lib -o bvi bvi.o comm.o set.o re.o io.o edit.o recomp.o /data/develop/android/sysroot/usr/lib/libncurses.a
[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/bvi-1.4.2 ] $

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/bvi-1.4.2 ] $ ls -ltr bvi

-rwxrwxr-x. 1 xtrnaw7 xtrnaw7 394448 Dec  8 16:55 bvi
[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/bvi-1.4.2 ] $

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/bvi-1.4.2 ] $ file bvi

bvi: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, stripped
[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/bvi-1.4.2 ] $


Test the result:

Copy the binary just created to the phone :

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/bvi-1.4.2 ] $ adb push bvi /data/local/tmp
bvi: 1 file pushed, 0 skipped. 77.2 MB/s (394448 bytes in 0.005s)
[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/bvi-1.4.2 ] $


And execute then in an adb shell these commands:

ASUS_I006D:/ $ ldd /data/local/tmp/bvi
    linux-vdso.so.1 => [vdso] (0x76b7504000)
    libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x76b6185000)
    libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x76b6093000)
ASUS_I006D:/ $

ASUS_I006D:/ $ /data/local/tmp/bvi --help
Usage: bvi [-R] [-c cmd | +cmd] [-f script]
       [-s skip] [-e end] [-n length] file ...
       file offset/size: 10k, 20m, 1g, 0x1000 hex, 0200 octal
1|ASUS_I006D:/ $


Notes

Other parameters used for dynamic libraries in the command to link the executables are "<libname>.la" : Files with the extension .la are description files for libraries.


Example:

/bin/sh ./libtool  --tag=CC   --mode=link /data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang -fsigned-char -fno-common -Wall -Wextra -Waddress-of-packed-member -Wembedded-directive -Wextra-semi -Wformat-security -Wimplicit-function-declaration -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wno-missing-field-initializers -Wold-style-definition -Wpointer-arith -Wredundant-decls -Wsign-compare -Wstrict-prototypes -Wtype-limits -Wuninitialized -Wunused-but-set-parameter -Wunused-but-set-variable -Wunused-parameter -Wunused-result -Wunused-variable -Wvla -Walloca -Werror=sequence-point -I./libsmartcols/src --sysroot /data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot  -O2 -fPIE -fPIC -I/data/develop/android/sysroot/usr/include   -Wno-implicit-function-declaration -Wno-int-conversion -D_PATH_VI=\"/system/bin/vi\"  -DHAVE_NANOSLEEP=1     --sysroot /data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot  -s -pie -L/data/develop/android/sysroot/usr/lib  -o lsclocks misc-utils/lsclocks-lsclocks.o  libcommon.la libsmartcols.la   


These parameters must also be replaced with the static library:

/data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang -fsigned-char -fno-common -Wall -Wextra -Waddress-of-packed-member -Wembedded-directive -Wextra-semi -Wformat-security -Wimplicit-function-declaration -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wno-missing-field-initializers -Wold-style-definition -Wpointer-arith -Wredundant-decls -Wsign-compare -Wstrict-prototypes -Wtype-limits -Wuninitialized -Wunused-but-set-parameter -Wunused-but-set-variable -Wunused-parameter -Wunused-result -Wunused-variable -Wvla -Walloca -Werror=sequence-point -I./libsmartcols/src --sysroot /data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot  -O2 -fPIE -fPIC -I/data/develop/android/sysroot/usr/include   -Wno-implicit-function-declaration -Wno-int-conversion -D_PATH_VI=\"/system/bin/vi\"  -DHAVE_NANOSLEEP=1     --sysroot /data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot  -s -pie -L/data/develop/android/sysroot/usr/lib  -o lsclocks misc-utils/lsclocks-lsclocks.o ./.libs/libcommon.a ./.libs/libsmartcols.a  


The description files with the extension .la may contain the names of additional libraries required by the library - therefore you should check the contents of the *.la files (*.la files are plain text files); Example:

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/util-linux-2.40 ] $ grep dependency_libs= ./.libs/libmount.la
dependency_libs=' -L/data/develop/android/sysroot/usr/lib /data/develop/android/source/util-linux-2.40/libblkid.la'
[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/util-linux-2.40 ] $


The *.la files are usually located in the directory containing the library files.

Sometimes .so libraries are used in the make parameter without the "-l" option, example:

/data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang -fsigned-char -fno-common -Wall -Wextra -Waddress-of-packed-member -Wembedded-directive -Wextra-semi -Wformat-security -Wimplicit-function-declaration -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wno-missing-field-initializers -Wold-style-definition -Wpointer-arith -Wredundant-decls -Wsign-compare -Wstrict-prototypes -Wtype-limits -Wuninitialized -Wunused-but-set-parameter -Wunused-but-set-variable -Wunused-parameter -Wunused-result -Wunused-variable -Wvla -Walloca -Werror=sequence-point -I./libblkid/src -I./libsmartcols/src --sysroot /data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot -O2 -fPIE -fPIC -I/data/develop/android/sysroot/usr/include -Wno-implicit-function-declaration -Wno-int-conversion -D_PATH_VI=\"/system/bin/vi\" -DHAVE_NANOSLEEP=1 --sysroot /data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot -s -pie -o .libs/wipefs misc-utils/wipefs-wipefs.o  -L/data/develop/android/sysroot/usr/lib ./.libs/libblkid.so ./.libs/libcommon.a ./.libs/libsmartcols.so -L/system/lib

These parameter must also be replaced by the static libraries:

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/util-linux-2.40 ] $ /data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang -fsigned-char -fno-common -Wall -Wextra -Waddress-of-packed-member -Wembedded-directive -Wextra-semi -Wformat-security -Wimplicit-function-declaration -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wno-missing-field-initializers -Wold-style-definition -Wpointer-arith -Wredundant-decls -Wsign-compare -Wstrict-prototypes -Wtype-limits -Wuninitialized -Wunused-but-set-parameter -Wunused-but-set-variable -Wunused-parameter -Wunused-result -Wunused-variable -Wvla -Walloca -Werror=sequence-point -I./libblkid/src -I./libsmartcols/src --sysroot /data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot -O2 -fPIE -fPIC -I/data/develop/android/sysroot/usr/include -Wno-implicit-function-declaration -Wno-int-conversion -D_PATH_VI=\"/system/bin/vi\" -DHAVE_NANOSLEEP=1 --sysroot /data/develop/android/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot -s -pie -o .libs/wipefs misc-utils/wipefs-wipefs.o  -L/data/develop/android/sysroot/usr/lib ./.libs/libblkid.a ./.libs/libcommon.a ./.libs/libsmartcols.a -L/system/lib



Some dynamic libraries (*.so) require additional dynamic libraries. In this case, you must add the static version of these libraries to the link command.

Use the executable readelf to list the dynamic libraries required by a library, example:

┌shell@localhost:/data/local/tmp/test1/bvi-1.4.2
└─$ readelf -d /data/local/tmp/develop/sysroot/usr/lib/libnl-genl-3.so | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libnl-3.so.200]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so]
┌shell@localhost:/data/local/tmp/test1/bvi-1.4.2
└─$

readelf is part of the clang19 toolchain; the executable is also available here for download: http://bnsmb.de/files/public/Android/binaries_for_arm64/readelf 


Notes

see also How to compile a dynamic linked C++ binary without dependency on libc++_shared.so  



History of this entry

06.06.2026

added the info that statically linked binaries can not load dynamic libraries

19.04.2026

added the info about libraries required by a dynamic library

24.03.2026

added the info about how to get the list of libraries required by a library or executable

17.09.2025

added the link to the HowTo with instructions to compiled shared C++ binaries that use the static libc++ library.

22.01.2025

fixed some typos

08.12.2024

initial release

 
  

Examples for compiling programs on the PC using the Android NDK

 
 

Examples for compiling programs using the gcc from the Android NDK


Note 

Up until version 14b of the Android NDK, gcc was used as compiler. The gcc is not part of the Android NDK version 15 or newer.

As of 16.04.2026 the Android NDK version 14b is still available for download here:  https://github.com/android/ndk/wiki/Unsupported-Downloads 



How to compile pigz using the gcc from the Android NDK


How to compile pigz using the gcc from the Android NDK


Source: http://zlib.net/pigz


pigz can be compiled using the include files and libraries in the sysroot directory from the Android NDK (no other libraries are required)


1. Download the source code for pigz using

wget http://zlib.net/pigz/pigz-2.8.tar.gz


2. Unpack the tar file

tar -xf pigz-2.8.tar.gz

cd pigz-2.8


3. Correct the make file for pigz 

cp Makefile Makefile.org

# edit the Makefile ; the differences when done should look like this:

xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$ diff Makefile Makefile.org
1,3c1,3
< CC=/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9
< CFLAGS=--sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual
< LDFLAGS=--sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -pie
---
> CC=gcc
> CFLAGS=-O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual
> LDFLAGS=
8,9c8
< #LIBS=-lm -lpthread -lz
<LIBS=-lm -lz
---
> LIBS=-lm -lpthread -lz
xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$



4. Create the executable using make

make


Example output of the make command
xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$ make
/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9 --sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual   -c -o pigz.o pigz.c
/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9 --sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual   -c -o yarn.o yarn.c
/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9 --sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual   -c -o try.o try.c
/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9 --sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/deflate.c
/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9 --sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/blocksplitter.c
/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9 --sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/tree.c
/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9 --sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/lz77.c
/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9 --sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/cache.c
/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9 --sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/hash.c
/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9 --sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/util.c
/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9 --sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/squeeze.c
/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9 --sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/katajainen.c
/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9 --sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/symbols.c
/data/develop/android/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc-4.9 --sysroot=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64 -pie -o pigz pigz.o yarn.o try.o deflate.o blocksplitter.o tree.o lz77.o cache.o hash.o util.o squeeze.o katajainen.o symbols.o -lm -lz
ln -f pigz unpigz
xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$




5. Check the result

xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$ ls -l pigz
-rwxr-xr-x 2 xtrnaw7 xtrnaw7 148688 Feb 11 21:03 pigz

xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$ file pigz
pigz: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, not stripped
xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$



6.  Copy the executable pigz to the phone and test it

adb push pigz /sdcard/Download


And then in an adb shell on the phone:

ASUS_I006D:/ $ mv /sdcard/Download/pigz /data/local/tmp/
ASUS_I006D:/ $

ASUS_I006D:/ $ chmod 755 /data/local/tmp/pigz
ASUS_I006D:/ $

ASUS_I006D:/ $  /data/local/tmp/pigz -V                                                                                         

pigz 2.8
ASUS_I006D:/ $
 



How to compile the ncurses library using the gcc from the Android NDK


How to compile the ncurses library using the gcc from the Android NDK

Source:  https://www.gnu.org/software/ncurses/


Download and unpack the source files for ncurses:

wget https://ftp.gnu.org/gnu/ncurses/ncurses-6.3.tar.gz
tar -xzf ncurses-6.3.tar.gz
cd ncurses-6.3/



Prepare the environment for running ./configure to create the make files:

# for the ASUS Zenfone 8 use
#
export TARGET=aarch64-linux-android

# Set this to your minSdkVersion.
#
export API=21

export NDK="/data/develop/android/android-ndk-r14b"

export  CFLAGS="--sysroot=${NDK}/platforms/android-${API}/arch-arm64 -fPIE"
export LDFLAGS="--sysroot=${NDK}/platforms/android-${API}/arch-arm64 -pie"

export CC="${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/${TARGET}-gcc-4.9"
export AR="${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/${TARGET}-gcc-ar"
export LD="${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/${TARGET}-gcc-ld"
export CXX="${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/${TARGET}-c++"
export RANLIB="${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/${TARGET}-ranlib"
export STRIP="${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/${TARGET}-strip"
export AS="${CC}"



Use ./configure to create the make files:

export STRIPPROG=${STRIP}
INSTALL=$PWD/install-sh ./configure  --prefix=/data/develop/android/android_root/usr --host ${TARGET}



Notes:

At least in Fedora 39 the executable /usr/bin/install (which is used by default in the script ./configure) uses the binary strip found in the PATH and ignores the environment variable. But the strip from Fedora can not handle executables for the ARM CPUs so it can not be used for installing files for ARM CPUs. STRIPPROG Is the environment variable used in install-sh for the strip executable to use.


Important are the last lines of the output of ./configure:

** Configuration summary for NCURSES 6.3 20211021:

       extended funcs: yes
       xterm terminfo: xterm-new

        bin directory: /data/develop/android/android_root/usr/bin
        lib directory: /data/develop/android/android_root/usr/lib
    include directory: /data/develop/android/android_root/usr/include/ncurses
        man directory: /data/develop/android/android_root/usr/share/man
   terminfo directory: /data/develop/android/android_root/usr/share/terminfo

** Include-directory is not in a standard location



Now create the library using make:

make


When done install the ncurses library and include files in the sysroot directory for Android :

make install


To check the result list the files in the sysroot directory:

example
xtrnaw7@fedora01:/data/develop/android/source/bvi-1.4.2$ ls -l /data/develop/android/android_root/usr/include/
total 2
drwxr-xr-x 2 xtrnaw7 xtrnaw7 11 Feb 12 15:27 ncurses
lrwxrwxrwx 1 xtrnaw7 xtrnaw7 19 Feb 12 13:20 ncurses.h -> ./ncurses/ncurses.h
xtrnaw7@fedora01:/data/develop/android/source/bvi-1.4.2$


xtrnaw7@fedora01:/data/develop/android/source/bvi-1.4.2$
ls -l /data/develop/android/android_root/usr/lib
total 1770
-rw-r--r-- 1 xtrnaw7 xtrnaw7  808984 Feb 12 15:27 libncurses.a
-rw-r--r-- 1 xtrnaw7 xtrnaw7 3571844 Feb 12 15:27 libncurses_g.a
lrwxrwxrwx 1 xtrnaw7 xtrnaw7      17 Feb 12 13:30 terminfo -> ../share/terminfo
xtrnaw7@fedora01:/data/develop/android/source/bvi-1.4.2$




 

 

How to compile bvi using the gcc from the Android NDK


How to compile bvi using the gcc from the Android NDK


Source:  https://bvi.sourceforge.net/


bvi requires the library ncurses which is not part of the sysroot from the Android NDK


Download the source for bvi

wget http://sourceforge.net/projects/bvi/files/bvi/1.4.2/bvi-1.4.2.src.tar.gz/download -O bvi-1.4.2.src.tar.gz

and unpack the tar file

tar -xf bvi-1.4.2.src.tar.gz
cd bvi-1.4.2



Prepare the environment for running ./configure to create the make files:

# for the ASUS Zenfone 8 use
#
export TARGET=aarch64-linux-android

# Set this to your minSdkVersion.
#
export API=21

export NDK=/data/develop/android/android-ndk-r25.2

export TOOLCHAIN=${NDK}/toolchains/llvm/prebuilt/linux-x86_64

export CFLAGS="--sysroot ${TOOLCHAIN}/sysroot -fPIE"
export LDFLAGS="--sysroot ${TOOLCHAIN}/sysroot -pie"

export CC="${TOOLCHAIN}/bin/$TARGET$API-clang"
export AR="${TOOLCHAIN}/bin/llvm-ar"
export AS="${CC}"
export CXX="${TOOLCHAIN}/bin/$TARGET$API-clang++"
export LD="${TOOLCHAIN}/bin/ld"
export RANLIB="${TOOLCHAIN}/bin/llvm-ranlib"
export STRIP="${TOOLCHAIN}/bin/llvm-strip"

# include the additional sysroot directories with the files for the ncurses library
#
export CFLAGS="-w --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -I/data/develop/android/android_root/usr/include  -Wno-implicit-function-declaration -Wno-int-conversion"
export LDFLAGS="--sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -pie -L/data/develop/android/android_root/usr/lib"



Note:

Normally you should fix the reason for the warnings and not suppress them with compiler options like -Wno-implicit-function-declaration -Wno-int-conversion.


Edit the input file config.h.in for the script ./configure to request the usage of the replacement function for rpl_malloc and rpl_realloc:

cp config.h.in  config.h.in.org

sed -i -e "/#undef malloc/d" -e "/#undef realloc/d"   config.h.in

xtrnaw7@fedora01:/data/develop/android/source/bvi/bvi-1.4.2$ diff config.h.in  config.h.in.org
134a135
> #undef malloc
139a141
> #undef realloc
xtrnaw7@fedora01:/data/develop/android/source/bvi/bvi-1.4.2$



Create the make files using the script ./configure:

./configure  --prefix=/data/develop/android/android_root/usr --host $TARGET


Create the binary using make:

make -j$( nproc )


Check the result:

xtrnaw7@fedora01:/data/develop/android/source/bvi-1.4.2$ ls -l bvi
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 322840 Feb 12 11:48 bvi
xtrnaw7@fedora01:/data/develop/android/source/bvi-1.4.2$

xtrnaw7@fedora01:/data/develop/android/source/bvi-1.4.2$ file bvi
bvi: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, not stripped
xtrnaw7@fedora01:/data/develop/android/source/bvi-1.4.2$



copy the binary to the phone:

adb push bvi /sdcard/Download


and then in an adb shell on the phone:

cp /sdcard/Download/bvi /data/local/tmp/
chmod 755 /data/local/tmp/bvi
/data/local/tmp/bvi -h



example:

ASUS_I006D:/ $ /data/local/tmp/bvi -h
Usage: bvi [-R] [-c cmd | +cmd] [-f script]
       [-s skip] [-e end] [-n length] file ...
       file offset/size: 10k, 20m, 1g, 0x1000 hex, 0200 octal
1|ASUS_I006D:/ $

 



How to compile nmon using the gcc from the Android NDK


How to compile nmon using the gcc from the Android NDK


Source:
https://nmon.sourceforge.io/pmwiki.php

nmon require ncurses  

Download the source file for nmon; as of 19.04.2026 the current version of the source file is lmon16s.c.


API="21"

NDK="/data/develop/android/android-ndk-r14b"

NDK_SYSROOT="${NDK}/platforms/android-${API}/arch-arm64"
NDK_TOOLCHAIN="${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64"
NDK_BINDIR="${NDK_TOOLCHAIN}/bin"

SYSROOT="/data/develop/android/android_root"

${NDK_BINDIR}/aarch64-linux-android-gcc-4.9 --sysroot=${NDK_SYSROOT} -I${SYSROOT}/usr/include -fPIE lmon16s.c -o nmon \
   -L${SYSROOT}/usr/lib -pie -D arm64 -Wno-format-security -Wno-format -lncurses -O3 -Wall -D JFS -D GETUSER -D LARGEMEM -g



Update 12.08.2024


To create a static linked binary use

${NDK_BINDIR}/aarch64-linux-android-gcc-4.9 --sysroot=${NDK_SYSROOT} -I${SYSROOT}/usr/include -fPIE lmon16s.c -o nmon \
   -L${SYSROOT}/usr/lib -static -D arm64 -Wno-format-security -Wno-format -lncurses -O3 -Wall -D JFS -D GETUSER -D LARGEMEM -g


Note:

If the compiler complains about a missing fstab.h, create a dummy fstab.h file:

touch ${SYSROOT}/usr/include/fstab.h

(Note: nmon does not list any infos about the filesystems using this work around)






How to compile less using the gcc from the Android NDK


How to compile less using the gcc from the Android NDK


Source:  http://ftp.fau.de/gnu/less/less-643.tar.gz

less requires ncurses


export API="21"

export NDK="/data/develop/android/android-ndk-r14b"

export NDK_SYSROOT="${NDK}/platforms/android-${API}/arch-arm64"
export NDK_TOOLCHAIN="${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64"
export NDK_BINDIR="${NDK_TOOLCHAIN}/bin"

export SYSROOT="/data/develop/android/android_root"

export CC="${NDK_BINDIR}/aarch64-linux-android-gcc-4.9"
export AR="${NDK_BINDIR}/aarch64-linux-android-ar"
export LD="${NDK_BINDIR}/aarch64-linux-android-ld"
export CXX="${NDK_BINDIR}/aarch64-linux-android-c++"
export RANLIB="${NDK_BINDIR}/aarch64-linux-android-ranlib"
export STRIP="${NDK_BINDIR}/aarch64-linux-android-strip"
export AS="${NDK_BINDIR}/aarch64-linux-android-as"

export CFLAGS="--sysroot=${NDK_SYSROOT}  -fPIE -I${
SYSROOT}/usr/include"
export LDFLAGS="--sysroot=${NDK_SYSROOT} -pie -L${SYSROOT}/usr/lib"

# for the ASUS Zenfone 8 use
#
export TARGET=aarch64-linux-android
 
./configure --host ${TARGET}

make





How to compile vim using the gcc from the Android NDK


How to compile vim using the gcc from the Android NDK 

Source: git clone https://github.com/vim/vim.git

vim requires libncurses, /data/develop/android/sysroot/usr/ is the directory tree with the required ncurses library in these instructions


# for static build:
    export CFLAGS="-static -O2"
    export LDFLAGS="-static -s"

# for dynamic build:
#  
#   export CFLAGS='-O2 -fPIE -fPIC'
#   export LDFLAGS='-s -pie'
#

# for the ASUS Zenfone 8 use
#
export TARGET=aarch64-linux-android

# Set this to your minSdkVersion.
#
export API=21

export NDK="/data/develop/android/android-ndk-r14b"

export SYSROOT="${NDK}/platforms/android-${API}/arch-arm64"

export  CFLAGS="--sysroot=${SYSROOT} ${CFLAGS}  -I/data/develop/android/sysroot/usr/include -I${SYSROOT}/usr/include "
export LDFLAGS="--sysroot=${SYSROOT} ${LDFLAGS} -L/data/develop/android/sysroot/usr/lib     -L${SYSROOT}/usr/lib "

export CPPFLAGS="${CFLAGS}"

export CC="${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/${TARGET}-gcc-4.9"
export AR=${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/${TARGET}-gcc-ar
export LD=${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/${TARGET}-gcc-ld
export CXX=${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/${TARGET}-c++
export RANLIB=${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/${TARGET}-ranlib
export STRIP=${NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/${TARGET}-strip
export AS=${CC}

./configure --host ${TARGET} --prefix=/data/local/tmp \
     --disable-nls \
     --with-tlib=ncurses \
     --without-x \
      --enable-gui=no \
      --enable-multibyte \
      --enable-terminal \
      remove_size \
       ac_cv_sizeof_int=4  \
       vim_cv_getcwd_broken=no \
       vim_cv_memmove_handles_overlap=yes \
       vim_cv_stat_ignores_slash=yes \
       vim_cv_tgetent=zero \
       vim_cv_terminfo=yes \
       vim_cv_toupper_broken=no \
       vim_cv_timer_create=yes \
       vim_cv_tty_group=world \
       --with-wayland=no

make -j$( nproc )


Most of the parameter for the configure script are taken from this script  https://github.com/Zackptg5/Cross-Compiled-Binaries-Android/blob/master/build_script/build.sh

Notes:

The default directories for the vim config files are defined in the file ./src/auto/pathdef.c:

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/source/vim ] $ grep _dir ./src/auto/pathdef.c
char_u *default_vim_dir = (char_u *)"/data/local/tmp/share/vim";
char_u *default_vimruntime_dir = (char_u *)"";
[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/source/vim ] $


This file is created by the make file ; to change the values for the directory use configure parameter to define these variables:

default_vim_dir
default_vimruntime_dir


---



How to compile Perl 5.40 using the gcc from the Android NDK


How to compile Perl 5.40 using the gcc from the Android NDK 

Source:  https://www.cpan.org/src/5.0/perl-5.40.0.tar.gz


Perl 5.40 can be compiled using the latest Android SDK with gcc -- this is SDK version r14b.

The build configuration for creating the binaries for Android can be done using the Script Configure that is part of the tar archive with the source files for Perl.

Be aware that the Configure script needs a working connection to a phone - either via adb or ssh (see the file README.android from the tar archive).

In the instructions below a connection to the phone via adb is used.


Use these commands to compile Perl 5.40 wit the Android SDK:


# Define the API version to use
#
export API=24

# define the target CPU; for the ASUS Zenfone 8 or any other phone with arm64 CPU use:
#
export TARGETARCH="aarch64-linux-android"

# define the target dir on the phone for the Perl installation
#
export PERL_TARGET_DIR_ON_THE_PHONE="/data/local/tmp/perl540"

# define the NDK to use
#
export NDK="/data/develop/android/android-ndk-r14b"

# add the NDK directory with the binaries to the PATH
#
export PATH="${NDK}/toolchains/${TARGETARCH}-4.9/prebuilt/`uname | tr '[A-Z]' '[a-z]'`-x86_64/bin:${PATH}"


# create a temporary tool chain to compile Perl 5.40 in /tmp

export ANDROID_TOOLCHAIN="/tmp/my-toolchain-${TARGETARCH}"

export SYSROOT=${ANDROID_TOOLCHAIN}/sysroot

# create the temporary tool chain directory
#
if [ ! -d "/tmp/my-toolchain-${TARGETARCH}/bin" ] ; then
   $NDK/build/tools/make-standalone-toolchain.sh  --platform=android-21   --install-dir="${ANDROID_TOOLCHAIN}"  --toolchain="${TARGETARCH}-4.9" --arch=arm64
fi


# define the s/n of the phone used -- if there is only one phone connected via this command can be used:
# (this variable is used as parameter for the adb command in the Configure script)
#
DEVICE="$( adb devices | tail -2 | awk '{ print $1 }' )"

# define the temporary directory on the phone used for compiling perl
#
export TARGETDIR="/data/local/tmp/perl_temp"

# test adb access (and create the test directory on the phone ...)
#
adb -s $DEVICE shell "mkdir -p ${TARGETDIR} ; ls -ld ${TARGETDIR}"

# Update 18.08.2024: Cleanup the temporary directory on the phone
#
adb -s $DEVICE shell "rm -rf ${TARGETDIR}/* ; ls -la ${TARGETDIR}"

#
# create the target directory for the Perl binaries on the phone temporary on the PC
# (the Configure script requires that these directories exist; the directories are only used when executing "make install")
#
mkdir -p "${PERL_TARGET_DIR_ON_THE_PHONE}/bin"
mkdir -p "${PERL_TARGET_DIR_ON_THE_PHONE}/../bin"


# start the Configure script from Perl - note: Do NOT use the parameter "-d -e" ; using these parameter the Configure script always fails
# And I recommend not to use the parameter "-s" to see what's going on (-s = silent run)
#
./Configure -Dprefix="${PERL_TARGET_DIR_ON_THE_PHONE}"  -Dusedevel -Dusecrosscompile -Dtargetrun=adb -Dcc=${TARGETARCH}-gcc -Dsysroot="${SYSROOT}" -Dtargetdir="${TARGETDIR}"  -Dtargethost=${DEVICE} \
   -Dccflags=" -fPIE -pie --std=gnu99 --sysroot=${SYSROOT} " \
   -Dldflags="-pie --sysroot=${SYSROOT} -L${ANDROID_TOOLCHAIN}/sysroot/usr/lib " \
   -Accflags=" -DPERL_LC_ALL_USES_NAME_VALUE_PAIRS -DPERL_LC_ALL_SEPARATOR -DPERL_LC_ALL_CATEGORY_POSITIONS_INIT"
  
The Configure script asks a lot of questions - for most of them the default value can be confirmed.

The only exception is this question:

Checking for GNU cc in disguise and/or its version number...
"./try": error: Android 5.0 and later only support position-independent executables (-fPIE).
You are not using GNU cc.
./Configure: line 4727: ./try: cannot execute binary file: Exec format error
./Configure: line 4727: ./try: cannot execute binary file: Exec format error
./Configure: line 4727: ./try: cannot execute binary file: Exec format error
Your C compiler doesn't seem to be able to compile C99 code
Do you really want to continue? [n]

Just ignore the error and answer "y".

Reason:

The Configure script does not use the correct parameter for the gcc to create the test binary. Therefor the gcc successfully creates the test binary without error but the binary can not be executed in the Android OS.

So far I have not found out how to define the gcc parameters for this test compilation: The parameters for Configure script are not used here; the file hints/linux-android.sh is not yet read, and environment variables are also ignored as far as I can see.

To avoid this error you can edit the Configure script: see https://dev.to/jccr/compiling-perl-for-android-12a4 for details.


Another question for which you might want to not use the default value is this one:

Do you want to use a version number suffix for installed binaries? [y] n

If using the default (y) the Configure script creates a perl executable called "perl5.40.0" instead of "perl".


Use

make

to create the binaries.


To create the directory structure for Perl later on the phone execute on the PC:

make install


Now create a zip file or archive from the directory /data/local/tmp/perl540 and copy it to the phone


To cleanup the temporary directories used use these commands

# delete the temporary tool chain
#
rm -rf "${ANDROID_TOOLCHAIN}"

# delete the directory on the phone with the temporary files
#
adb shell rm -rf "${TARGETDIR}"


Notes

To install the Perl files into another directory use the command

make install DESTDIR=<install_dir_for_perl>


The config.sh file used to build Perl 5.40 using the Android SDK r14b is config.sh_for_perl_5.40_in_Android_sdk_r14b.

These instructions can also be used to compile Perl 5.38

see the section How to compile Perl for Android for instructions to compile Perl 5.38 in a Termux session



Before starting a make test you must delete two lines for non-existent files from the file Makefile.SH (the files for the Pod-Parser are not part of the standard Perl anymore):

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/perl-5.40.0 ] $ cp Makefile.SH Makefile.SH.org

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/perl-5.40.0 ] $ sed -i -e "/.*Pod-Parser.*/d"  Makefile.SH

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/perl-5.38.0 ] $ diff Makefile.SH Makefile.SH.org
1559a1560
>     $to cpan/Pod-Parser/*
1565a1567
>     $to cpan/Pod-Parser/lib/*
[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/source/perl-5.38.0 ] $


The log file of "make test" for the Perl 5.40 executables created is make_test_for_perl540.txt.



  

How to compile OpenSSL using the gcc from the Android NDK


How to compile OpenSSL using the gcc from the Android NDK

Source: https://github.com/openssl/openssl/releases/download/openssl-3.3.1/openssl-3.3.1.tar.gz


To compile OpenSSL for arm64 using the NDK only a few environment variables are necessary:

export TARGET=aarch64-linux-android
export ANDROID_NDK_ROOT="/data/develop/android/android-ndk-r14b"
export PATH=${ANDROID_NDK_ROOT}/toolchains/${TARGET}-4.9/prebuilt/linux-x86_64/bin:$PATH

./Configure android-arm64


Notes:

Make sure that no other environment variables for cross compiling are defined before calling the Configure script!

Check the file NOTES-ANDROID.md in the OpenSSL source for further info regardind compiling OpenSSL for Android

To use "make install" to install the compiled OpenSSL libraries into the NDK use the additional parameter

--prefix=/data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64

android-24 is the API version used to compile the OpenSSL binaries; without the parameter to define the API version the Configure script from the OpenSSL source uses the latest API available in the used NDK, to print that version use the command

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/source/openssl-3.3.1 ] $ ls -ld /data/develop/android/android-ndk-r14b/platforms/android-*/arch-arm64
drwxr-xr-x. 3 xtrnaw7 xtrnaw7 4096 Mar 15  2017 /data/develop/android/android-ndk-r14b/platforms/android-21/arch-arm64
drwxr-xr-x. 3 xtrnaw7 xtrnaw7 4096 Mar 15  2017 /data/develop/android/android-ndk-r14b/platforms/android-22/arch-arm64
drwxr-xr-x. 3 xtrnaw7 xtrnaw7 4096 Mar 15  2017 /data/develop/android/android-ndk-r14b/platforms/android-23/arch-arm64
drwxr-xr-x. 3 xtrnaw7 xtrnaw7 4096 Mar 15  2017 /data/develop/android/android-ndk-r14b/platforms/android-24/arch-arm64
[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/source/openssl-3.3.1 ] $


To use another API version use the additional parameter -D__ANDROID_API__=N for the Configure script.






Examples for compiling programs using the clang from the Android NDK



Note

The clang compiler has been used since version 15 of the Android NDK.



How to compile pigz using the clang from the Android NDK


How to compile pigz using the clang from the Android NDK

Source:  http://zlib.net/pigz/ 


pigz can be compiled using the include files and libraries in the sysroot directory from the Android NDK (no other libraries are required)

1. Download the source code for pigz using

wget http://zlib.net/pigz/pigz-2.8.tar.gz


2. Unpack the tar file

tar -xf pigz-2.8.tar.gz

cd pigz-2.8


3. Correct the make file for pigz 

cp Makefile Makefile.org

# edit the Makefile ; the differences when done should look like this:

xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$ diff Makefile Makefile.org
1,3c1,3
< CC=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang
< CFLAGS= --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual
< LDFLAGS=--sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -pie
---
> CC=gcc
> CFLAGS=-O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual
> LDFLAGS=
8,9c8
< #LIBS=-lm -lpthread -lz
< LIBS=-lm -lz
---
> LIBS=-lm -lpthread -lz
xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$



4. Create the executable using make

make


Example output of the make command
xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$ make
/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual   -c -o pigz.o pigz.c
/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual   -c -o yarn.o yarn.c
/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual   -c -o try.o try.c
/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/deflate.c
/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/blocksplitter.c
/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/tree.c
/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/lz77.c
/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/cache.c
/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/hash.c
/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/util.c
/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/squeeze.c
zopfli/src/zopfli/squeeze.c:346:10: warning: variable 'total_length_test' set but not used [-Wunused-but-set-variable]
  size_t total_length_test = 0;
         ^
1 warning generated.
/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/katajainen.c
/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -c zopfli/src/zopfli/symbols.c
/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang --sysroot= --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -pie -o pigz pigz.o yarn.o try.o deflate.o blocksplitter.o tree.o lz77.o cache.o hash.o util.o squeeze.o katajainen.o symbols.o -lm -lz
ln -f pigz unpigz
xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$




5. Check the result

xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$ ls -l pigz
-rwxr-xr-x 2 xtrnaw7 xtrnaw7 144256 Feb 12 07:20 pigz
xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$

xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$ file pigz
pigz: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, not stripped
xtrnaw7@fedora01:/data/develop/android/source/pigz-2.8$



6.  Copy the executable pigz to the phone and test it

adb push pigz /sdcard/Download


And then in an adb shell on the phone:

ASUS_I006D:/ $ cp /sdcard/Download/pigz /data/local/tmp/pigz
ASUS_I006D:/ $

ASUS_I006D:/ $ chmod 755 /data/local/tmp/pigz
ASUS_I006D:/ $

ASUS_I006D:/ $ file /data/local/tmp/pigz
/data/local/tmp/pigz: ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), for Android 21, built by NDK r25 (8775105), not stripped
ASUS_I006D:/ $

ASUS_I006D:/ $  /data/local/tmp/pigz  -V
pigz 2.8
ASUS_I006D:/ $



How to compile the ncurses library using the clang from the Android NDK


How to compile the ncurses library using the clang from the Android NDK


Source:  https://ftp.gnu.org/gnu/ncurses/


Download and unpack the source files for ncurses:

wget https://ftp.gnu.org/gnu/ncurses/ncurses-6.3.tar.gz
tar -xzf ncurses-6.3.tar.gz
cd ncurses-6.3/



Prepare the environment for running ./configure to create the make files:

# for the ASUS Zenfone 8 use
#
export TARGET=aarch64-linux-android

# Set this to your minSdkVersion.
#
export API=21

export NDK=/data/develop/android/android-ndk-r25.2

export TOOLCHAIN=${NDK}/toolchains/llvm/prebuilt/linux-x86_64

export  CFLAGS="--sysroot ${TOOLCHAIN}/sysroot -fPIE"
export LDFLAGS="--sysroot ${TOOLCHAIN}/sysroot -pie"

export CC=${TOOLCHAIN}/bin/$TARGET$API-clang
export AR=${TOOLCHAIN}/bin/llvm-ar
export AS=${CC}
export CXX=${TOOLCHAIN}/bin/$TARGET$API-clang++
export LD=${TOOLCHAIN}/bin/ld
export RANLIB=${TOOLCHAIN}/bin/llvm-ranlib
export STRIP=${TOOLCHAIN}/bin/llvm-strip



Use ./configure to create the make files:

exportSTRIPPROG=${STRIP}
INSTALL=$PWD/install-sh ./configure  --prefix=/data/develop/android/android_root/usr --host ${TARGET}



Notes:

At least in Fedora 39 the executable /usr/bin/install (which is used by default in the script configure) uses the binary strip found in the PATH and ignores the environment variable. But the strip from Fedora can not handle executables for the ARM CPUs so it can not be used for installing files for ARM CPUs. STRIPPROG Is the environment variable used in install-sh for the strip executable to use.



Important are the last lines of the output of ./configure:

** Configuration summary for NCURSES 6.3 20211021:

       extended funcs: yes
       xterm terminfo: xterm-new

        bin directory: /data/develop/android/android_root/usr/bin
        lib directory: /data/develop/android/android_root/usr/lib
    include directory: /data/develop/android/android_root/usr/include/ncurses
        man directory: /data/develop/android/android_root/usr/share/man
   terminfo directory: /data/develop/android/android_root/usr/share/terminfo

** Include-directory is not in a standard location



Now create the library using make:

make -j$( nproc )


When done install the ncurses library and include files in the sysroot directory for Android :

make install


To check the result list the files in the sysroot directory:

example
xtrnaw7@fedora01:/data/develop/android/source/ncurses-6.3$ ls -l /data/develop/android/android_root/usr/include/
total 2
drwxr-xr-x 2 xtrnaw7 xtrnaw7 11 Feb 12 13:32 ncurses
lrwxrwxrwx 1 xtrnaw7 xtrnaw7 19 Feb 12 13:20 ncurses.h -> ./ncurses/ncurses.h
xtrnaw7@fedora01:/data/develop/android/source/ncurses-6.3$
 
xtrnaw7@fedora01:/data/develop/android/source/ncurses-6.3$ ls -l /data/develop/android/android_root/usr/lib/
total 1801
-rw-r--r-- 1 xtrnaw7 xtrnaw7  848880 Feb 12 13:32 libncurses.a
-rw-r--r-- 1 xtrnaw7 xtrnaw7 3303892 Feb 12 13:32 libncurses_g.a
lrwxrwxrwx 1 xtrnaw7 xtrnaw7      17 Feb 12 13:30 terminfo -> ../share/terminfo
xtrnaw7@fedora01:/data/develop/android/source/ncurses-6.3$






How to compile bvi using the clang from the Android NDK


How to compile bvi using the clang from the Android NDK


Source: http://sourceforge.net/projects/bvi

bvi
requires the library ncurses which is not part of the sysroot from the Android NDK.


Download the source for bvi

wget http://sourceforge.net/projects/bvi/files/bvi/1.4.2/bvi-1.4.2.src.tar.gz/download -O bvi-1.4.2.src.tar.gz

and unpack the tar file

tar -xf bvi-1.4.2.src.tar.gz
cd bvi-1.4.2



Prepare the environment for running ./configure to create the make files:

# for the ASUS Zenfone 8 use
#
export TARGET=aarch64-linux-android

# Set this to your minSdkVersion.
#
export API=21

export NDK=/data/develop/android/android-ndk-r25.2

export TOOLCHAIN=${NDK}/toolchains/llvm/prebuilt/linux-x86_64

export CFLAGS="--sysroot ${TOOLCHAIN}/sysroot -fPIE"
export LDFLAGS="--sysroot ${TOOLCHAIN}/sysroot -pie"

export CC=${TOOLCHAIN}/bin/$TARGET$API-clang
export AR=${TOOLCHAIN}/bin/llvm-ar
export AS=${CC}
export CXX=${TOOLCHAIN}/bin/$TARGET$API-clang++
export LD=${TOOLCHAIN}/bin/ld
export RANLIB=${TOOLCHAIN}/bin/llvm-ranlib
export STRIP=${TOOLCHAIN}/bin/llvm-strip

# include the additional sysroot directories with the files for the ncurses library
#
export CFLAGS="-w --sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIE -I/data/develop/android/android_root/usr/include  -Wno-implicit-function-declaration -Wno-int-conversion"
export LDFLAGS="--sysroot=/data/develop/android/android-ndk-r25.2/toolchains/llvm/prebuilt/linux-x86_64/sysroot -pie -L/data/develop/android/android_root/usr/lib"



Note:

Normally you should fix the reason for the warnings and not suppress them with compiler options like -Wno-implicit-function-declaration -Wno-int-conversion.


Edit the input file config.h.in for the script configure to request the usage of the replacement function for rpl_malloc and rpl_realloc:

cp config.h.in  config.h.in.org


# edit config.h.in and delete the lines:

#undef realloc
#undef malloc

->

xtrnaw7@fedora01:/data/develop/android/source/bvi/bvi-1.4.2$ diff config.h.in  config.h.in.org
134a135
> #undef malloc
139a141
> #undef realloc
xtrnaw7@fedora01:/data/develop/android/source/bvi/bvi-1.4.2$



Create the make files using the script ./configure:

./configure  --prefix=/data/develop/android/android_root/usr --host $TARGET


Create the binary using make:

make


Check the result:

xtrnaw7@fedora01:/data/develop/android/source/bvi-1.4.2$ ls -l bvi
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 322840 Feb 12 11:48 bvi
xtrnaw7@fedora01:/data/develop/android/source/bvi-1.4.2$

xtrnaw7@fedora01:/data/develop/android/source/bvi-1.4.2$ file bvi
bvi: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, not stripped
xtrnaw7@fedora01:/data/develop/android/source/bvi-1.4.2$



copy the binary to the phone:

adb push bvi /sdcard/Download


and then in an adb shell on the phone:

cp /sdcard/Download/bvi /data/local/tmp/
chmod 755 /data/local/tmp/bvi
/data/local/tmp/bvi-h


example:

ASUS_I006D:/ $ /data/local/tmp/bvi -h
Usage: bvi [-R] [-c cmd | +cmd] [-f script]
       [-s skip] [-e end] [-n length] file ...
       file offset/size: 10k, 20m, 1g, 0x1000 hex, 0200 octal
1|ASUS_I006D:/ $ 

 



How to compile cpio using clang from the Android NDK


How to compile cpio using the clang from the Android NDK


Source: http://ftp.fau.de/gnu/cpio/cpio-2.9.tar.gz

cpio does not need any additional library


export API="21"

export NDK="/data/develop/android/android-ndk-r25.2"

export NDK_TOOLCHAIN="${NDK}/toolchains/llvm/prebuilt/linux-x86_64"
export NDK_BINDIR="${NDK_TOOLCHAIN}/bin"
export NDK_SYSROOT="${NDK_TOOLCHAIN}/sysroot/"
export SYSROOT="/data/develop/android/android_root"

export CC="${NDK_BINDIR}/aarch64-linux-android${API}-clang"
export AR="${NDK_BINDIR}/llvm-ar"
export LD="${NDK_BINDIR}/ld"
export CXX="${NDK_BINDIR}/aarch64-linux-android${API}-clang++"
export RANLIB="${NDK_BINDIR}/llvm-ranlib"
export STRIP="${NDK_BINDIR}/llvm-strip"
export AS="${NDK_BINDIR}/aarch64-linux-android${API}-clang"

export CFLAGS="--sysroot=${NDK_SYSROOT}  -fPIE"
export LDFLAGS="--sysroot=${NDK_SYSROOT} -pie"

./configure  --prefix=/data/develop/android/android_root/ --host arm
make 






How to compile bc using clang from the Android NDK


How to compile bc using the clang from the Android NDK


Source:  http://ftp.fau.de/gnu/bc/bc-1.07.tar.gz

bc does not need any additional library


export API="21"

export NDK="/data/develop/android/android-ndk-r25.2"

export NDK_TOOLCHAIN="${NDK}/toolchains/llvm/prebuilt/linux-x86_64"
export NDK_BINDIR="${NDK_TOOLCHAIN}/bin"
export NDK_SYSROOT="${NDK_TOOLCHAIN}/sysroot/"
export SYSROOT="/data/develop/android/android_root"

export CC="${NDK_BINDIR}/aarch64-linux-android${API}-clang"
export AR="${NDK_BINDIR}/llvm-ar"
export LD="${NDK_BINDIR}/ld"
export CXX="${NDK_BINDIR}/aarch64-linux-android${API}-clang++"
export RANLIB="${NDK_BINDIR}/llvm-ranlib"
export STRIP="${NDK_BINDIR}/llvm-strip"
export AS="${NDK_BINDIR}/aarch64-linux-android${API}-clang"

export CFLAGS="--sysroot=${NDK_SYSROOT}  -fPIE"
export LDFLAGS="--sysroot=${NDK_SYSROOT} -pie"

./configure --host arm64
make




How to compile libnl3 using clang from the Android NDK


How to compile libnl3 using the clang from the Android NDK


Source:  https://github.com/thom311/libnl/releases/download/libnl3_9_0/libnl-3.9.0.tar.gz


export API="26"

export NDK="/data/develop/android/android-ndk-r25.2"

export NDK_TOOLCHAIN="${NDK}/toolchains/llvm/prebuilt/linux-x86_64"
export NDK_BINDIR="${NDK_TOOLCHAIN}/bin"
export NDK_SYSROOT="${NDK_TOOLCHAIN}/sysroot/"
export SYSROOT="/data/develop/android/android_root"

export CC="${NDK_BINDIR}/aarch64-linux-android${API}-clang"
export AR="${NDK_BINDIR}/llvm-ar"
export LD="${NDK_BINDIR}/ld"
export CXX="${NDK_BINDIR}/aarch64-linux-android${API}-clang++"
export RANLIB="${NDK_BINDIR}/llvm-ranlib"
export STRIP="${NDK_BINDIR}/llvm-strip"
export AS="${NDK_BINDIR}/aarch64-linux-android${API}-clang"

export CFLAGS="--sysroot=${NDK_SYSROOT}  -fPIC"
export LDFLAGS="--sysroot=${NDK_SYSROOT} -pie"

./configure --prefix=/data/develop/android/android_root/usr  --host="aarch64-linux-android" --disable-pthreads

sed -i '/^struct in_addr/itypedef __be32 in_addr_t;' include/linux-private/linux/in.h

make

Credits: https://github.com/thom311/libnl/issues/279
  



How to compile libpcap using clang from the Android NDK


How to compile libpcap using the clang from the Android NDK


Source:  https://www.tcpdump.org/release/libpcap-1.10.1.tar.gz 

libpcap requires libnl3


export API="26"

export NDK="/data/develop/android/android-ndk-r25.2"

export NDK_TOOLCHAIN="${NDK}/toolchains/llvm/prebuilt/linux-x86_64"
export NDK_BINDIR="${NDK_TOOLCHAIN}/bin"
export NDK_SYSROOT="${NDK_TOOLCHAIN}/sysroot/"
export SYSROOT="/data/develop/android/android_root"

export CC="${NDK_BINDIR}/aarch64-linux-android${API}-clang"
export AR="${NDK_BINDIR}/llvm-ar"
export LD="${NDK_BINDIR}/ld"
export CXX="${NDK_BINDIR}/aarch64-linux-android${API}-clang++"
export RANLIB="${NDK_BINDIR}/llvm-ranlib"
export STRIP="${NDK_BINDIR}/llvm-strip"
export AS="${NDK_BINDIR}/aarch64-linux-android${API}-clang"

export CFLAGS="--sysroot=${NDK_SYSROOT}  -fPIC -I/data/develop/android/android_root/usr/include"
export LDFLAGS="--sysroot=${NDK_SYSROOT} -pie  -L
/data/develop/android/android_root/usr/lib"

./configure --prefix=/data/develop/android/android_root/usr --host="aarch64-linux-android"

make




How to compile ngrep using clang from the Android NDK


How to compile ngrep using the clang from the Android NDK


Source:  https://github.com/jpr5/ngrep/archive/refs/heads/master.zip

ngrep requires libpcap


The file ngrep.c must be changed to compile the source code for Android:

replace the line

#include <netinet/igmp.h>

with

#ifdef __ANDROID__

struct igmp {
    unsigned char igmp_type;    // Type of message
    unsigned char igmp_code;    // Code
    unsigned short igmp_cksum;  // Checksum
    unsigned int igmp_group;    // Group address
};

#else

#include <netinet/igmp.h>

#endif


Then execute

export API="26"

export NDK="/data/develop/android/android-ndk-r25.2"

export NDK_TOOLCHAIN="${NDK}/toolchains/llvm/prebuilt/linux-x86_64"
export NDK_BINDIR="${NDK_TOOLCHAIN}/bin"
export NDK_SYSROOT="${NDK_TOOLCHAIN}/sysroot/"
export SYSROOT="/data/develop/android/android_root"

export CC="${NDK_BINDIR}/aarch64-linux-android${API}-clang"
export AR="${NDK_BINDIR}/llvm-ar"
export LD="${NDK_BINDIR}/ld"
export CXX="${NDK_BINDIR}/aarch64-linux-android${API}-clang++"
export RANLIB="${NDK_BINDIR}/llvm-ranlib"
export STRIP="${NDK_BINDIR}/llvm-strip"
export AS="${NDK_BINDIR}/aarch64-linux-android${API}-clang"

export CFLAGS="--sysroot=${NDK_SYSROOT}  -fPIC -I/data/develop/android/android_root/usr/include -Wno-implicit-int -Wno-deprecated-non-prototype"
export LDFLAGS="--sysroot=${NDK_SYSROOT} -pie  -L
/data/develop/android/android_root/usr/lib"

# create the Make files
#
./configure --prefix=/data/develop/android/android_root/usr  --host="aarch64-linux-android"

# if the Makefile in the directory regex-0.12 was not generated by the configure, create it manually using the following commands

cd ./regex-0.12 && ./configure --prefix=/data/develop/android/android_root/usr  --host="aarch64-linux-android"


# correct the make file for the regex library if necessary
#
sed -i -e "s#^CFLAGS =#CFLAGS=${CFLAGS} #g"  regex-0.12/Makefile

# ngrep uses some deprecated pcap functions (the ngrep source code was last updated 2017)
#
cp  $SYSROOT//usr/include/pcap/pcap.h $SYSROOT//usr/include/pcap/pcap.h.org
sed -i -e "s/PCAP_DEPRECATED.*//g"  $SYSROOT//usr/include/pcap/pcap.h

# there is an hardcoded include for /usr/include/pcap in the Makefile that must be removed
#
cp Makefile Makefile.org
sed -i -e "s#-I/usr/include/pcap##g" Makefile

make





How to compile a static linked bvi using clang from the Android NDK


How to compile a static linked bvi using the clang from the Android NDK


Source: http://sourceforge.net/projects/bvi/files/bvi/1.4.2/bvi-1.4.2.src.tar.gz


Prepare the config files for bvi :

cp config.h.in  config.h.in.org

sed -i -e "/#undef malloc/d" -e "/#undef realloc/d"  config.h.in


The result should look like this:

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/source/test/bvi-1.4.2 ] $ diff config.h.in  config.h.in.org
134a135
> #undef malloc
139a141
> #undef realloc
[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/source/test/bvi-1.4.2 ] $




# for static build:
    export CFLAGS="-static -O2"
    export LDFLAGS="-static -s -ffunction-sections -fdata-sections -Wl,--gc-sections "


# for dynamic build:

#   export CFLAGS='-O2 -fPIE -fPIC'
#   export LDFLAGS='-s -pie'
#

# for the ASUS Zenfone 8 use
#
export TARGET=aarch64-linux-android

# Set this to your minSdkVersion.
#
export API=21

export NDK=/data/develop/android/android-ndk-r25.2

export TOOLCHAIN=${NDK}/toolchains/llvm/prebuilt/linux-x86_64

export CFLAGS="--sysroot ${TOOLCHAIN}/sysroot ${CFLAGS}"
export LDFLAGS="--sysroot ${TOOLCHAIN}/sysroot ${LDFLAGS}"

export CC=${TOOLCHAIN}/bin/$TARGET$API-clang
export AR=${TOOLCHAIN}/bin/llvm-ar
export AS=${CC}
export CXX=${TOOLCHAIN}/bin/$TARGET$API-clang++
export LD=${TOOLCHAIN}/bin/ld
export RANLIB=${TOOLCHAIN}/bin/llvm-ranlib
export STRIP=${TOOLCHAIN}/bin/llvm-strip

# include the additional sysroot directories with the files for the ncurses library
#
export CFLAGS="${CFLAGS} -w  -I/data/develop/android/sysroot/usr/include  -Wno-implicit-function-declaration -Wno-int-conversion"
export LDFLAGS="${LDFLAGS}   -L/data/develop/android/android_root/usr/lib"

./configure --host ${TARGET} --with-ncurses=/data/develop/android/sysroot/usr/

make




How to compile NcFTP using clang from the Android NDK


How to compile NcFTP using the clang from the Android NDK


Source: https://www.ncftp.com/public_ftp/ncftp/ncftp-3.3.0-src.tar.gz


Download and unpack the tar file

export CFLAGS="-static -O2  "  # -fPIC
export LDFLAGS="-static -s  "  # -ffunction-sections -fdata-sections -Wl,--gc-sections "

#
# for the ASUS Zenfone 8 or other phones with ARM64 CPU use:
#
export TARGET=aarch64-linux-android
export TOOLS_IDENTIFIER=aarch64-linux-android


export TARGET_ROOT=/data/develop/android/sysroot

# Set this to your minSdkVersion.
# (newer APIs do not work)
#
export API=${API:=26}

export NDK=/data/develop/android/android-ndk-r25.2
export ANDROID_NDK_HOME=${NDK}

export TOOLCHAIN=${NDK}/toolchains/llvm/prebuilt/linux-x86_64

export SYSROOT="${TOOLCHAIN}/sysroot"

export CFLAGS="--sysroot ${SYSROOT} ${CFLAGS}"
export LDFLAGS="--sysroot ${SYSROOT} ${LDFLAGS}"

export CC=${TOOLCHAIN}/bin/$TOOLS_IDENTIFIER$API-clang
export AR=${TOOLCHAIN}/bin/llvm-ar
export AS=${CC}
export CXX=${TOOLCHAIN}/bin/$TOOLS_IDENTIFIER$API-clang++
export LD=${TOOLCHAIN}/bin/ld
export RANLIB=${TOOLCHAIN}/bin/llvm-ranlib
export STRIP=${TOOLCHAIN}/bin/llvm-strip

# include the additional sysroot directories with the files for the ncurses library
#
export CFLAGS="${CFLAGS} -w  -I${TARGET_ROOT}/usr/include -I${SYSROOT}/usr/include -Wno-implicit-function-declaration -Wno-int-conversion"
export LDFLAGS="${LDFLAGS}   -L${TARGET_ROOT}/usr/lib -L${SYSROOT}/lib "

./configure --host ${TARGET} --target=${TARGET} --prefix=/system --without-curses --without-ncurses

make -j$( nproc )


If the NcFTP binaries fail like this:

[clang19 toolchain] [root@localhost /data/local/tmp]# ./ncftp
error: "./ncftp": executable's TLS segment is underaligned: alignment is 8, needs to be at least 64 for ARM64 Bionic
Aborted
[clang19 toolchain] [root@localhost /data/local/tmp]#

align the binary using the script align_fix.py:

[xtrnaw7@t15g /data/develop/android/test/ncftp-3.3.0]$ cd bin
[xtrnaw7@t15g /data/develop/android/test/ncftp-3.3.0/bin]$

[xtrnaw7@t15g /data/develop/android/test/ncftp-3.3.0/bin]$ for i in * ; do echo "*** $i:" ;  /data/develop/android/source/align_fix.py $i ; done
*** ncftp:
Found TLS segment with align = 8
TLS segment is underaligned, patching
*** ncftpbatch:
Found TLS segment with align = 8
TLS segment is underaligned, patching
*** ncftpget:
Found TLS segment with align = 8
TLS segment is underaligned, patching
*** ncftpls:
Found TLS segment with align = 8
TLS segment is underaligned, patching
*** ncftpput:
Found TLS segment with align = 8
TLS segment is underaligned, patching
*** ncftpspooler:
Found TLS segment with align = 64
[xtrnaw7@t15g /data/develop/android/test/ncftp-3.3.0/bin]$





Examples for compiling programs using a recent GCC cross-compiler




How to compile pigz using a recent GCC cross-compiler


How to compile pigz using a recent GCC cross-compiler

Source: http://zlib.net/pigz


pigz can be compiled using the include files and libraries in the sysroot directory from the Android NDK (no other libraries are required)


1. Download the source code for pigz using

wget http://zlib.net/pigz/pigz-2.8.tar.gz


2. Unpack the tar file

tar -xf pigz-2.8.tar.gz

cd pigz-2.8


3. Correct the make file for pigz (for the Android API 36 in this example)

cp Makefile Makefile.org

cat >Makefile.patch <<-\EOT
--- Makefile.org    2026-05-31 20:05:57.303318902 +0200
+++ Makefile    2026-06-01 11:06:53.298447781 +0200
@@ -1,11 +1,11 @@
-CC=gcc
-CFLAGS=-O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual
+CC=aarch64-unknown-linux-android36-gcc
+CFLAGS=-O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36
 LDFLAGS=
 # CFLAGS=-O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -g -fsanitize=thread
 # LDFLAGS=-g -fsanitize=thread
 # CFLAGS=-O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -g -fsanitize=address
 # LDFLAGS=-g -fsanitize=address
-LIBS=-lm -lpthread -lz
+LIBS=-lm  -lz
 ZOPFLI=zopfli/src/zopfli/
 ZOP=deflate.o blocksplitter.o tree.o lz77.o cache.o hash.o util.o squeeze.o katajainen.o symbols.o

EOT

patch <Makefile.patch


4. Create the binary using make:

make


5. Test the binary

adb push pigz /data/local/tmp && adb shell /data/local/tmp/pigz -h


Example
[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$ wget http://zlib.net/pigz/pigz-2.8.tar.gz
Saving 'pigz-2.8.tar.gz'
HTTP response 200 OK [http://zlib.net/pigz/pigz-2.8.tar.gz]
pigz-2.8.tar.gz      100% [==================================================================================>]  118.46K    --.-KB/s
                          [Files: 1  Bytes: 118.46K [147.15KB/s] Redirects: 0  Todo: 0  Errors: 0             ]
[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$ tar -xf pigz-2.8.tar.gz
[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$ cd pigz-2.8
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$ cp Makefile Makefile.org
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$ cat >Makefile.patch <<-\EOT
--- Makefile.org    2026-05-31 20:05:57.303318902 +0200
+++ Makefile    2026-06-01 11:06:53.298447781 +0200
@@ -1,11 +1,11 @@
-CC=gcc
-CFLAGS=-O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual
+CC=aarch64-unknown-linux-android36-gcc
+CFLAGS=-O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36
 LDFLAGS=
 # CFLAGS=-O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -g -fsanitize=thread
 # LDFLAGS=-g -fsanitize=thread
 # CFLAGS=-O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual -g -fsanitize=address
 # LDFLAGS=-g -fsanitize=address
-LIBS=-lm -lpthread -lz
+LIBS=-lm  -lz
 ZOPFLI=zopfli/src/zopfli/
 ZOP=deflate.o blocksplitter.o tree.o lz77.o cache.o hash.o util.o squeeze.o katajainen.o symbols.o
EOT
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$ patch <Makefile.patch
patching file Makefile
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$ diff Makefile.org Makefile
1,2c1,2
< CC=gcc
< CFLAGS=-O3 -Wall -Wextra -Wno-unknown-pragmas -Wcast-qual
---
> CC=aarch64-unknown-linux-android36-gcc
> CFLAGS=-O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36
8c8
< LIBS=-lm -lpthread -lz
---
> LIBS=-lm  -lz
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$ make
aarch64-unknown-linux-android36-gcc -O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36   -c -o pigz.o pigz.c
aarch64-unknown-linux-android36-gcc -O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36   -c -o yarn.o yarn.c
aarch64-unknown-linux-android36-gcc -O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36   -c -o try.o try.c
aarch64-unknown-linux-android36-gcc -O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36 -c zopfli/src/zopfli/deflate.c
aarch64-unknown-linux-android36-gcc -O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36 -c zopfli/src/zopfli/blocksplitter.c
aarch64-unknown-linux-android36-gcc -O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36 -c zopfli/src/zopfli/tree.c
aarch64-unknown-linux-android36-gcc -O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36 -c zopfli/src/zopfli/lz77.c
aarch64-unknown-linux-android36-gcc -O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36 -c zopfli/src/zopfli/cache.c
aarch64-unknown-linux-android36-gcc -O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36 -c zopfli/src/zopfli/hash.c
aarch64-unknown-linux-android36-gcc -O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36 -c zopfli/src/zopfli/util.c
aarch64-unknown-linux-android36-gcc -O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36 -c zopfli/src/zopfli/squeeze.c
In function ‘LZ77OptimalRun’,
    inlined from ‘ZopfliLZ77OptimalFixed’ at zopfli/src/zopfli/squeeze.c:553:3:
zopfli/src/zopfli/squeeze.c:440:3: warning: ‘length_array’ may be used uninitialized [-Wmaybe-uninitialized]
  440 |   TraceBackwards(inend - instart, length_array, path, pathsize);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
zopfli/src/zopfli/squeeze.c: In function ‘ZopfliLZ77OptimalFixed’:
zopfli/src/zopfli/squeeze.c:317:13: note: by argument 2 of type ‘const short unsigned int *’ to ‘TraceBackwards.constprop’ declared here
  317 | static void TraceBackwards(size_t size, const unsigned short* length_array,
      |             ^~~~~~~~~~~~~~
aarch64-unknown-linux-android36-gcc -O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36 -c zopfli/src/zopfli/katajainen.c
aarch64-unknown-linux-android36-gcc -O3 -Wextra -Wno-unknown-pragmas -Wcast-qual --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36 -c zopfli/src/zopfli/symbols.c
aarch64-unknown-linux-android36-gcc  -o pigz pigz.o yarn.o try.o deflate.o blocksplitter.o tree.o lz77.o cache.o hash.o util.o squeeze.o katajainen.o symbols.o -lm  -lz
ln -f pigz unpigz
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$ ls -l pigz
-rwxrwxr-x. 2 xtrnaw7 xtrnaw7 148856 Jun  1 11:39 pigz
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$ file pigz
pigz: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, BuildID[sha1]=91fb255148aecfa2afd528649efe6d814ac264fd, for Android 36, built by NDK r30-beta1 (14904198), not stripped
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$ adb push pigz /data/local/tmp && adb shell /data/local/tmp/pigz -h
pigz: 1 file pushed, 0 skipped. 47.9 MB/s (148856 bytes in 0.003s)
Usage: pigz [options] [files ...]
  will compress files in place, adding the suffix '.gz'. If no files are
  specified, stdin will be compressed to stdout. pigz does what gzip does,
  but spreads the work over multiple processors and cores when compressing.

Options:
  -0 to -9, -11        Compression level (level 11, zopfli, is much slower)
  --fast, --best       Compression levels 1 and 9 respectively
  -A, --alias xxx      Use xxx as the name for any --zip entry from stdin
  -b, --blocksize mmm  Set compression block size to mmmK (default 128K)
  -c, --stdout         Write all processed output to stdout (won't delete)
  -C, --comment ccc    Put comment ccc in the gzip or zip header
  -d, --decompress     Decompress the compressed input
  -f, --force          Force overwrite, compress .gz, links, and to terminal
  -F  --first          Do iterations first, before block split for -11
  -h, --help           Display a help screen and quit
  -H, --huffman        Use only Huffman coding for compression
  -i, --independent    Compress blocks independently for damage recovery
  -I, --iterations n   Number of iterations for -11 optimization
  -J, --maxsplits n    Maximum number of split blocks for -11
  -k, --keep           Do not delete original file after processing
  -K, --zip            Compress to PKWare zip (.zip) single entry format
  -l, --list           List the contents of the compressed input
  -L, --license        Display the pigz license and quit
  -m, --no-time        Do not store or restore mod time
  -M, --time           Store or restore mod time
  -n, --no-name        Do not store or restore file name or mod time
  -N, --name           Store or restore file name and mod time
  -O  --oneblock       Do not split into smaller blocks for -11
  -p, --processes n    Allow up to n compression threads (default is the
                       number of online processors, or 8 if unknown)
  -q, --quiet          Print no messages, even on error
  -r, --recursive      Process the contents of all subdirectories
  -R, --rsyncable      Input-determined block locations for rsync
  -S, --suffix .sss    Use suffix .sss instead of .gz (for compression)
  -t, --test           Test the integrity of the compressed input
  -U, --rle            Use run-length encoding for compression
  -v, --verbose        Provide more verbose output
  -V  --version        Show the version of pigz
  -Y  --synchronous    Force output file write to permanent storage
  -z, --zlib           Compress to zlib (.zz) instead of gzip format
  --                   All arguments after "--" are treated as files
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/pigz-2.8]$


 


History of this entry

20.01.2026

initial release





How to compile the ncurses library using a recent GCC cross-compiler


How to compile the ncurses library using a recent GCC cross-compiler

Source:  https://www.gnu.org/software/ncurses/


Download and unpack the source files for ncurses:

wget https://ftp.gnu.org/gnu/ncurses/ncurses-6.3.tar.gz
tar -xzf ncurses-6.3.tar.gz
cd ncurses-6.3/


Prepare the environment for running ./configure to create the make files:


export API=36
export CROSS_COMPILER_DIR="/data/develop/android/cross_compile/android-gcc-16.1.1-cross/bin"

export CC="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android${API}-gcc "
export AR="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-ar"
export LD="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-ld"
export CXX="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android${API}-g++"
export RANLIB="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-ranlib"
export STRIP="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-strip"
export AS="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-as"
export CPP="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-cpp"

export CFLAGS="-w  --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android${API} "
export CFLAGS="${CFLAGS} -Wno-implicit-function-declaration -Wno-int-conversion"

export
CFLAGS="
${CFLAGS} -DHAVE_GETTIMEOFDAY=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_TIME_SELECT=1 -D_XOPEN_SOURCE=600 -D_GNU_SOURCE"

export LDFLAGS="--sysroot
/data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android${API}"


Use ./configure to create the make files:

export TARGET=aarch64-linux-android
export STRIPPROG=${STRIP}
INSTALL=$PWD/install-sh ./configure  --prefix=/data/develop/android/cross_compile/sysroot_temp  --host ${TARGET}


Notes:

At least in Fedora 39 the executable /usr/bin/install (which is used by default in the script ./configure) uses the binary strip found in the PATH and ignores the environment variable. But the strip binary from Fedora can not handle executables for the ARM CPUs so it can not be used for installing files for ARM CPUs. STRIPPROG Is the environment variable used in install-sh for the strip executable to use.


Now create the library using make:

make


When done install the ncurses library and include files using the command:

make install


Example
[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$ wget https://ftp.gnu.org/gnu/ncurses/ncurses-6.3.tar.gz
Saving 'ncurses-6.3.tar.gz'
HTTP response 200 OK [https://ftp.gnu.org/gnu/ncurses/ncurses-6.3.tar.gz]
ncurses-6.3.tar.gz   100% [==================================================================================>]    3.41M    5.50MB/s
                          [Files: 1  Bytes: 3.41M [2.27MB/s] Redirects: 0  Todo: 0  Errors: 0                 ]
[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$ tar -xzf ncurses-6.3.tar.gz
[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$
[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$ cd ncurses-6.3/
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export API=36
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export CROSS_COMPILER_DIR="/data/develop/android/cross_compile/android-gcc-16.1.1-cross/bin"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export CC="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android${API}-gcc "
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export AR="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-ar"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export LD="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-ld"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export CXX="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android${API}-g++"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export RANLIB="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-ranlib"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export STRIP="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-strip"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export AS="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-as"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export CPP="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-cpp"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export CFLAGS="-w  --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android${API} "
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export CFLAGS="-w  --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android${API} "
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export CFLAGS="${CFLAGS} -Wno-implicit-function-declaration -Wno-int-conversion"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export CFLAGS="${CFLAGS} -DHAVE_GETTIMEOFDAY=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_TIME_SELECT=1 -D_XOPEN_SOURCE=600 -D_GNU_SOURCE"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export LDFLAGS="--sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android${API}"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export TARGET=aarch64-linux-android
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ export STRIPPROG=${STRIP}
$
 [xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ INSTALL=$PWD/install-sh ./configure  --prefix=/data/develop/android/cross_compile/sysroot_temp  --host ${TARGET}
configure: WARNING: If you wanted to set the --build type, don't use --host.
    If a cross compiler is detected then cross compile mode will be used.
checking for ggrep... no
...
Creating headers.sh
** Configuration summary for NCURSES 6.3 20211021:

       extended funcs: yes
       xterm terminfo: xterm-new

        bin directory: /data/develop/android/cross_compile/sysroot_temp/bin
        lib directory: /data/develop/android/cross_compile/sysroot_temp/lib
    include directory: /data/develop/android/cross_compile/sysroot_temp/include/ncurses
        man directory: /data/develop/android/cross_compile/sysroot_temp/share/man
   terminfo directory: /data/develop/android/cross_compile/sysroot_temp/share/terminfo

** Include-directory is not in a standard location
fgrep: warning: fgrep is obsolescent; using grep -F
fgrep: warning: fgrep is obsolescent; using grep -F
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ make -j16
( cd man && make DESTDIR="" RPATH_LIST="/data/develop/android/cross_compile/sysroot_temp/lib" all )
make[1]: Entering directory '/data/develop/android/cross_compile/temp/ncurses-6.3/man'
...
/data/develop/android/cross_compile/android-gcc-16.1.1-cross/bin/aarch64-unknown-linux-android36-g++  -o demo ../objects/demo.o -L../lib -lncurses++ -L../lib -lform -lmenu -lpanel -lncurses   --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36     -DHAVE_CONFIG_H -DBUILDING_NCURSES_CXX -I../c++ -I. -I../include -DHAVE_GETTIMEOFDAY=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_TIME_SELECT=1 -D_XOPEN_SOURCE=600 -D_GNU_SOURCE -DNDEBUG -g -O2  -DNCURSES_STATIC
make[1]: Leaving directory '/data/develop/android/cross_compile/temp/ncurses-6.3/c++'
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ 

xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$ make install
( cd man && make DESTDIR="" RPATH_LIST="/data/develop/android/cross_compile/sysroot_temp/lib" install )
make[1]: Entering directory '/data/develop/android/cross_compile/temp/ncurses-6.3/man'
...

make[1]: Leaving directory '/data/develop/android/cross_compile/temp/ncurses-6.3/c++'
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/ncurses-6.3]$




History of this entry

20.01.2026

initial release





How to compile bvi using a recent GCC cross-compiler


How to compile bvi using a recent GCC cross-compiler

Source:  https://bvi.sourceforge.net/


bvi requires the library ncurses which is not part of the sysroot from the Android NDK


Download the source for bvi:

wget http://sourceforge.net/projects/bvi/files/bvi/1.4.2/bvi-1.4.2.src.tar.gz/download -O bvi-1.4.2.src.tar.gz

and unpack the tar file

tar -xf bvi-1.4.2.src.tar.gz
cd bvi-1.4.2


Prepare the environment for running ./configure to create the make files:

export API=36
export CROSS_COMPILER_DIR="/data/develop/android/cross_compile/android-gcc-16.1.1-cross/bin"

export CC="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android${API}-gcc "
export AR="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-ar"
export LD="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-ld"
export CXX="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android${API}-g++"
export RANLIB="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-ranlib"
export STRIP="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-strip"
export AS="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-as"
export CPP="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-cpp"

export CFLAGS="-w  --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android${API} "
export CFLAGS="${CFLAGS} -Wno-implicit-function-declaration -Wno-int-conversion"

export LDFLAGS="--sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android${API}"


Edit the input file config.h.in for the script ./configure to request the usage of the replacement function for rpl_malloc and rpl_realloc:

cp config.h.in  config.h.in.org

sed -i -e "/#undef malloc/d" -e "/#undef realloc/d"   config.h.in


Create the make files using the script ./configure:

export TARGET=aarch64-linux-android
./configure  --prefix=/data/develop/android/cross_compile/sysroot_temp --host $TARGET --with-ncurses="/data/develop/android/cross_compile/sysroot_temp/"


Create the binary using make:

make


Check the result:

adb push bvi /data/local/tmp/ && adb  shell -t /data/local/tmp/bvi  -h


Example
[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$ wget http://sourceforge.net/projects/bvi/files/bvi/1.4.2/bvi-1.4.2.src.tar.gz/download -O bvi-1.4.2.src.tar.gz
HSTS in effect for sourceforge.net:80
HTTP response 302  [https://sourceforge.net/projects/bvi/files/bvi/1.4.2/bvi-1.4.2.src.tar.gz/download]
Enqueue https://downloads.sourceforge.net/project/bvi/bvi/1.4.2/bvi-1.4.2.src.tar.gz?ts=gAAAAABqHVYEK5obYvUTKFuuzGj54XWfvjgImT6zing4LHTTP response 302  [https://downloads.sourceforge.net/project/bvi/bvi/1.4.2/bvi-1.4.2.src.tar.gz?ts=gAAAAABqHVYEK5obYvUTKFuuzGj54XWfvEnqueuehttps://master.dl.sourceforge.net/project/bvi/bvi/1.4.2/bvi-1.4.2.src.tar.gz?viasf=1&fid=da56a6e36c29399f
Saving 'bvi-1.4.2.src.tar.gz'
HTTP response 200 OK [https://master.dl.sourceforge.net/project/bvi/bvi/1.4.2/bvi-1.4.2.src.tar.gz?viasf=1&fid=da56a6e36c29399f]
bvi-1.4.2.src.tar.gz 100% [==================================================================================>]  144.84K  612.28KB/s
                          [Files: 1  Bytes: 145.83K [71.27KB/s] Redirects: 2  Todo: 0  Errors: 0              ]
[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$ tar -xf bvi-1.4.2.src.tar.gz
[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp]$ cd bvi-1.4.2
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$  export API=36
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$  export CROSS_COMPILER_DIR="/data/develop/android/cross_compile/android-gcc-16.1.1-cross/bin"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$  export CC="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android${API}-gcc "
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$  export AR="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-ar"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$  export LD="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-ld"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$  export CXX="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android${API}-g++"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$  export RANLIB="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-ranlib"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$  export STRIP="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-strip"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$  export AS="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-as"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$  export CPP="${CROSS_COMPILER_DIR}/aarch64-unknown-linux-android-cpp"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$  export CFLAGS="-w  --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android${API} "
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$  export CFLAGS="${CFLAGS} -Wno-implicit-function-declaration -Wno-int-conversion"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$  export LDFLAGS="--sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android${API}"
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$ cp config.h.in  config.h.in.org
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$ sed -i -e "/#undef malloc/d" -e "/#undef realloc/d"   config.h.in
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$ diff config.h.in  config.h.in.org
134a135
> #undef malloc
139a141
> #undef realloc
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$ export TARGET=aarch64-linux-android
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$ ./configure  --prefix=/data/develop/android/cross_compile/sysroot_temp --host $TARGET --with-ncurses="/data/develop/android/cross_compile/sysroot_temp/"
checking for aarch64-linux-android-gcc... /data/develop/android/cross_compile/android-gcc-16.1.1-cross/bin/aarch64-unknown-linux-android36-gcc
checking whether the C compiler works... yes
...
checking for GNU libc compatible malloc... no
checking for stdlib.h... (cached) yes
checking for GNU libc compatible realloc... no
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$ make
/data/develop/android/cross_compile/android-gcc-16.1.1-cross/bin/aarch64-unknown-linux-android36-gcc  -w  --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36  -Wno-implicit-function-declaration -Wno-int-conversion  -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -I/data/develop/android/cross_compile/sysroot_temp//include -I/data/develop/android/cross_compile/sysroot_temp//include/ncurses -DHAVE_CONFIG_H -c bvi.c
...
/data/develop/android/cross_compile/android-gcc-16.1.1-cross/bin/aarch64-unknown-linux-android36-gcc  -w  --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36  -Wno-implicit-function-declaration -Wno-int-conversion  -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -I/data/develop/android/cross_compile/sysroot_temp//include -I/data/develop/android/cross_compile/sysroot_temp//include/ncurses -DHAVE_CONFIG_H -c bm_unix.c
/data/develop/android/cross_compile/android-gcc-16.1.1-cross/bin/aarch64-unknown-linux-android36-gcc  --sysroot /data/develop/android/cross_compile/android-gcc-16.1.1-cross/aarch64-unknown-linux-android36 -L/data/develop/android/cross_compile/sysroot_temp//lib -o bmore bmore.o bm_unix.o recomp.o -lncurses
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$ ls -l bvi
-rwxrwxr-x. 1 xtrnaw7 xtrnaw7 430824 Jun  1 11:52 bvi
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$ file bvi
bvi: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, BuildID[sha1]=47487d01d8c5b9f37caa2f0f46ee3ca25aec3bb0, for Android 36, built by NDK r30-beta1 (14904198), not stripped
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$

[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$ adb push bvi /data/local/tmp/ && adb  shell -t /data/local/tmp/bvi  -h
bvi: 1 file pushed, 0 skipped. 84.4 MB/s (430824 bytes in 0.005s)
Usage: bvi [-R] [-c cmd | +cmd] [-f script]
       [-s skip] [-e end] [-n length] file ...
       file offset/size: 10k, 20m, 1g, 0x1000 hex, 0200 octal
[xtrnaw7@t15g /data/develop/android/cross_compile/temp/bvi-1.4.2]$





History of this entry

20.01.2026

initial release



 

Examples for compiling programs on the phone running Android



Examples for compiling programs in Termux



How to compile pigz for Android in Termux



How to compile pigz for Android in Termux


Source:
http://zlib.net/pigz


1. Download the source code for pigz

wget http://zlib.net/pigz/pigz-2.8.tar.gz


2. Unpack the tar file

tar -xf pigz-2.8.tar.gz

cd pigz-2.8


3. Correct the make file for pigz :

cp Makefile  Makefile.org

sed -i -e "s/-lpthread//g" -e  "s/^CFLAGS=/CFLAGS=-fPIE -fPIC /g" -e "s/^LDFLAGS=/LDFLAGS=-pie /g"    Makefile


# Check the result

diff Makefile  Makefile.org

4. Create the binary

make



History of this entry

19.04.2026

initial release





How to compile the ncurses library for Android in Termux



How to compile the ncurses library for Android in Termux


Source:  https://www.gnu.org/software/ncurses/


Download and unpack the source files for ncurses:

wget https://ftp.gnu.org/gnu/ncurses/ncurses-6.3.tar.gz
tar -xzf ncurses-6.3.tar.gz
cd ncurses-6.3/



Use ./configure to create the make files:

./configure CFLAGS="-fPIE -fPIC -pie" LDFLAGS="-pie " --prefix=/data/data/com.termux/files/home/sysroot

and build the library:

make

use

make install

to install the library.



History of this entry

18.04.2026

initial release





How to compile bvi for Android in Termux



How to compile bvi for Android in Termux


Source:  https://bvi.sourceforge.net/)


Download the source for bvi:

wget http://sourceforge.net/projects/bvi/files/bvi/1.4.2/bvi-1.4.2.src.tar.gz/download -O bvi-1.4.2.src.tar.gz

and unpack the tar file

tar -xf bvi-1.4.2.src.tar.gz
cd bvi-1.4.2



Create the make file:

./configure CFLAGS="-fPIE -fPIC -pie" LDFLAGS="-pie " --with-ncurses=/data/data/com.termux/files/home/sysroot


And create the binary:

make



History of this entry

18.04.2026

initial release





How to compile Perl for Android in Termux


URL: https://xdaforums.com/t/how-to-compile-c-programs-in-android.4683687/#post-89651799


How to compile Perl for Android in Termux

Perl for Android can be compiled in a Termux session .

Note:

There is already a Perl in the Termux environment but that Perl can not be used in an adb session.


With these instructions I have successfully compiled Perl 5.38 in a Termux session on a ASUS Zenfone 8 with arm64 CPU running OmniROM 14 (Android 14) (root access is required for some of the commands):

 
First download the Perl source code

wget https://www.cpan.org/src/5.0/perl-5.38.0.tar.gz

Then unpack the tar archive in a Termux session and change the working directory to the directory with the unpacked tar file:

tar -xf perl-5.38.0.tar.gz
cd perl-5.38.0


Before starting the configure script for Perl, the default settings for compiling Perl under Android must be corrected in the file hints/linux-android.sh:

Change the value for ldflags to

ldflags="$ldflags -L/system/lib64"

Change the value for libpth to

eval "libpth='$libpth /system/lib64 /vendor/libi64'"

(or create a new profile in the directory ./hints for Android on 64 Bit CPUs)


To create Perl binaries that can be used in an adb shell, the Perl binaries must be in a directory that the user shell can access. I use the directory

/data/local/tmp/perl538

for that purpose:

su - -c mkdir /data/local/tmp/perl538

su - -c mkdir /data/local/tmp/perl538/bin

su - -c mkdir /data/local/tmp/bin

These directories can not be accessed by the User for Termux in Android 14 and newer. Therefor temporary change the owner of that directory (these commands must be executed in a Termux session!):

su - -c chown -R $( id -un ):$(id -un ) /data/local/tmp/perl538

su - -c chown $( id -un ):$(id -un ) /data/local/tmp/bin


(The Configure script expects the bin directories to already exist)

Next configure the environment to compile Perl -- either using the default values for compiling Perl without user input:

bash Configure -esd -Alibpth="/system/lib64 /vendor/lib64" -Dprefix=/data/local/tmp/perl538

or by manually entering the configuration values:

bash Configure -es -Alibpth="/system/lib64 /vendor/lib64" -Dprefix=/data/local/tmp/perl538

(Configure is a script in the tar file with the source code for Perl)

If you use the script Configure in interactive mode (without the parameter -d), enter this value for the compiler options to be used:

-fno-strict-aliasing -pipe -fstack-protector-strong -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wno-implicit-function-declaration -Wno-unused-parameter -Wno-int-conversion -DHAS_GETNET_PROTOS

And enter these libraries to be used:

-lpthread -ldl -lm -lcrypt -lutil -lc -llog -landroid-shmem

For all other question of the Configure script you can confirm the default value.


If you use the script Configure in automatic mode (with the parameter -d ), you must then manually correct some values in the file config.sh created by the script Configure:

ccflags='-fno-strict-aliasing -pipe -fstack-protector-strong -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wno-implicit-function-declaration -Wno-unused-parameter -Wno-int-conversion -DHAS_GETNET_PROTOS'

perllibs='-lpthread -ldl -lm -lcrypt -lutil -lc -llog landroid-shmem'



Then start the build using the command

make


Check the result using

make test

afterwards.


To install Perl into the directory /data/local/tmp/perl538 SELinux must be temporary disabled:

# temporary disable SElinux
#
su - -c /system/bin/setenforce 0


Then install Perl into the directory /data/local/tmp/perl538 using the command:

make install


Afterwards correct the owner for the files in /data/local/tmp/perl538 :

su - -c chown -R shell:shell /data/local/tmp/perl538


and enable SELInux again:

# enable SElinux
#
su - -c /system/bin/setenforce 1


Trouble Shooting

If make install does not install Perl in the correct directory, check that the directory exists and the Termux user can write to that directory (the directory must already exist when the script Configure is executed). In addition, check the value for the entry installprefix in the file config.sh:

~/perl-5.38.0 $ grep installprefix ./config.sh
installprefix='/data/local/tmp/perl538'
installprefixexp='.../..'
~/perl-5.38.0 $



All directories with fully qualified path in the file config.sh must already exist:

Use

grep "='/" config.sh

to print these directories.

All directories with three dots in the file config.sh will be created by the make script

Use

grep "\.\.\." config.sh

to print these directories.



Notes


The CFLAG -DHAS_GETNET_PROTOS is probably not necessary if you answer the questions of the Script Configure correct -- but I do not know the correct answers ...


Compiling Perl 5.40 in Termux fails because the source code for the locale in Perl 5.40 contains new values that are unknown in the current version of Termux

Update 16.08.2024

Instructions to compile Perl 5.40 using the Android SDK can be found in the Examples for compiling C programs for Android using gcc or clang



The Termux version used to compile Perl 5.38 was:

termux-info
~/perl-5.38.0 $ date
Thu Aug  8 15:37:35 CEST 2024
~/perl-5.38.0 $

~/perl-5.38.0 $ termux-info
Termux Variables:
TERMUX_APP_PACKAGE_MANAGER=apt
TERMUX_APP__APK_FILE=/data/app/~~CuZfJRR0tYqSFU5MUu5zwQ==/com.termux-fFVK6EOrvGrJxRmu2pEEGQ==/base.apk
TERMUX_APP__APK_RELEASE=F_DROID
TERMUX_APP__APP_VERSION_CODE=1020
TERMUX_APP__APP_VERSION_NAME=0.119.0-beta.1
TERMUX_APP__DATA_DIR=/data/user/0/com.termux
TERMUX_APP__IS_DEBUGGABLE_BUILD=false
TERMUX_APP__IS_INSTALLED_ON_EXTERNAL_STORAGE=false
TERMUX_APP__PACKAGE_NAME=com.termux
TERMUX_APP__PID=4303
TERMUX_APP__TARGET_SDK=28
TERMUX_VERSION=0.119.0-beta.1
TERMUX__SE_FILE_CONTEXT=u:object_r:app_data_file:s0:c140,c256,c512,c768
TERMUX__SE_INFO=default:targetSdkVersion=28:complete
TERMUX__SE_PROCESS_CONTEXT=u:r:untrusted_app_27:s0:c140,c256,c512,c768
TERMUX__UID=10140
TERMUX__USER_ID=0
Packages CPU architecture:
aarch64
Subscribed repositories:
# sources.list
deb https://ro.mirror.flokinet.net/termux/termux-main stable main
# x11-repo (sources.list.d/x11.list)
deb https://ro.mirror.flokinet.net/termux/termux-x11 x11 main
# glibc-repo (sources.list.d/glibc.list)
deb https://packages-cf.termux.dev/apt/termux-glibc/ glibc stable
Updatable packages:
apt/stable 2.8.1 aarch64 [upgradable from: 2.7.14-1]
command-not-found/stable 2.4.0-36 aarch64 [upgradable from: 2.4.0-34]
curl/stable 8.9.1 aarch64 [upgradable from: 8.8.0]
git/stable 2.46.0 aarch64 [upgradable from: 2.45.2]
gst-plugins-bad/stable 1.24.6 aarch64 [upgradable from: 1.24.5]
gst-plugins-base/stable 1.24.6 aarch64 [upgradable from: 1.24.5]
gst-plugins-good/stable 1.24.6 aarch64 [upgradable from: 1.24.5]
gstreamer/stable 1.24.6 aarch64 [upgradable from: 1.24.5]
libc++/stable 27 aarch64 [upgradable from: 26b]
libcurl/stable 8.9.1 aarch64 [upgradable from: 8.8.0]
libheif/stable 1.18.2 aarch64 [upgradable from: 1.18.1]
libnotify/x11 0.8.3-1 aarch64 [upgradable from: 0.8.3]
libtirpc/stable 1.3.5 aarch64 [upgradable from: 1.3.4-1]
libx11/stable 1.8.10 aarch64 [upgradable from: 1.8.9]
libxslt/stable 1.1.42 aarch64 [upgradable from: 1.1.40]
libxtst/stable 1.2.5 aarch64 [upgradable from: 1.2.4]
ndk-multilib/stable 27 all [upgradable from: 26b]
ndk-sysroot/stable 27 aarch64 [upgradable from: 26b-3]
openssl/stable 1:3.3.1 aarch64 [upgradable from: 1:3.2.1-1]
python-pip/stable 24.2 all [upgradable from: 24.1.2]
readline/stable 8.2.13 aarch64 [upgradable from: 8.2.10]
termux-tools/stable 1.43.2 all [upgradable from: 1.43.1]
vulkan-loader-generic/stable 1.3.292 aarch64 [upgradable from: 1.3.290]
termux-tools version:
1.43.1
Android version:
14
Kernel build information:
Linux localhost 5.4.147-Omni-qgki-perf-gf532250e9298 #5 SMP PREEMPT Thu Jun 20 18:54:28 CEST 2024 aarch64 Android
Device manufacturer:
asus
Device model:
ASUS_I006D
LD Variables:
LD_LIBRARY_PATH=
LD_PRELOAD=/data/data/com.termux/files/usr/lib/libtermux-exec.so
~/perl-5.38.0 $






The config.sh file used to build Perl 5.38 on Android 14 is config.sh_for_perl_5.38_in_Android_14.

The log file of "make test" for the Perl 5.38 executables created is make_test_for_perl538.txt.



For those who only want to use Perl on their phone:

I created a Magisk Module with Perl 5.38 - see the list of Magisk Modules below.

see also here: How to compile Perl in Android with the clang19 toolchain on the phone



History of this entry

08.08.2024

initial release





Examples for compiling programs using the gcc toolchain in Android




How to compile pigz in Android using the gcc toolchain on the phone



How to compile pigz in Android using the gcc toolchain on the phone

Source:
http://zlib.net/pigz


1. Download the source code for pigz

wget http://zlib.net/pigz/pigz-2.8.tar.gz


2. Unpack the tar file

tar -xf pigz-2.8.tar.gz

cd pigz-2.8


3. Correct the make file for pigz 

cp Makefile  Makefile.org

sed -i -e "s/-lpthread//g" -e  "s/^CFLAGS=/CFLAGS=-fPIE -fPIC /g" -e "s/^LDFLAGS=/LDFLAGS=-pie /g"  -e "s/ln -f/ln -s -f/g"  Makefile


# Check the result

diff Makefile  Makefile.org

4. Create the binary

make



History of this entry

19.04.2026

initial release





How to compile the ncurses library in Android using the gcc toolchain on the phone



How to compile the ncurses library in Android using the gcc toolchain on the phone

Source:  https://www.gnu.org/software/ncurses/


Download and unpack the source files for ncurses:

wget https://ftp.gnu.org/gnu/ncurses/ncurses-6.3.tar.gz
tar -xzf ncurses-6.3.tar.gz
cd ncurses-6.3/



Use ./configure to create the make files:

./configure CFLAGS="-fPIE -fPIC -pie" LDFLAGS="-pie " --prefix=/data/local/tmp/test1/sysroot/

and build the library:

make

Use

make install

to intall the library.



History of this entry

18.04.2026

initial release





How to compile bvi in Android using the gcc toolchain on the phone



How to compile bvi in Android using the gcc toolchain on the phone

Source:  https://bvi.sourceforge.net/


Download the source for bvi:

wget http://sourceforge.net/projects/bvi/files/bvi/1.4.2/bvi-1.4.2.src.tar.gz/download -O bvi-1.4.2.src.tar.gz

and unpack the tar file

tar -xf bvi-1.4.2.src.tar.gz
cd bvi-1.4.2



Create the make file

./configure CFLAGS="-fPIE -fPIC -pie" LDFLAGS="-pie "   --with-ncurses=/data/local/tmp/test1/sysroot


And create the binary:

make



History of this entry

18.04.2026

initial release





How to compile python3 in Android using the gcc toolchain



How to compile python3 in Android using the gcc toolchain

The source code for Python3 can be compiled in Android using gcc. A Magisk Module with the gcc Toolchain for Android is available here:

https://github.com/Googlers-Repo/gcc/


After applying the patches for Python3 from the Termux repository entry for Python3 the sources can be compiled using these settings:


export CFLAGS="$CFLAGS -D__ANDROID_API__=21 -O3 -fPIE -pie"

export CPPFLAGS="$CFLAGS"

# target directory for the python files
#
export TARGET_ROOT=/data/local/tmp/python3.14

AC_OPTIONS="ac_cv_func_shm_unlink=no  ac_cv_func_shm_open=yesac_cv_posix_semaphores_enabled=yes ac_cv_func_linkat=no ac_cv_func_faccessat=no  ac_cv_file__dev_ptc=no"

eval ${AC_OPTIONS} ./configure  --prefix=${TARGET_ROOT}/usr --with-openssl=/data/local/tmp/develop/sysroot/usr \
  --enable-loadable-sqlite-extensions --enable-shared  --enable-pystats  --with-builtin-hashlib-hashes=md5,sha1,sha2,sha3,blake2,sha256,sha512 \
   --with-system-expat --without-ensurepip  --with-tzpath=/system/usr/share/zoneinfo --with-system_libmpdec


make


Trouble Shooting


If make stops with an error like this

error: /data/local/tmp/develop/cpython314/Programs/_freeze_module: Android only supports position-independent executables (-fPIE)

delete the not working binary and link it manually using the gcc command printed by make to create the binary with the additional parameter -fPIE and -pie.

e.g

Output of make:

...
gcc     -o Programs/_freeze_module Programs/_freeze_module.o Modules/getpath_noop.o Modules/getbuildinfo.o Parser/token.o  Parser/pegen.o Parser/pegen_errors.o Parser/action_helpers.o Parser/parser.o Parser/string_parser.o Parser/peg_api.o Parser/lexer/buffer.o Parser/lexer/lexer.o Parser/lexer/state.o Parser/tokenizer/file_tokenizer.o Parser/tokenizer/readline_tokenizer.o Parser/tokenizer/string_tokenizer.o Parser/tokenizer/utf8_tokenizer.o Parser/tokenizer/helpers.o Parser/myreadline.o Objects/abstract.o Objects/boolobject.o Objects/bytes_methods.o Objects/bytearrayobject.o Objects/bytesobject.o Objects/call.o Objects/capsule.o Objects/cellobject.o Objects/classobject.o Objects/codeobject.o Objects/complexobject.o Objects/descrobject.o Objects/enumobject.o Objects/exceptions.o Objects/genericaliasobject.o Objects/genobject.o Objects/fileobject.o Objects/floatobject.o Objects/frameobject.o Objects/funcobject.o Objects/iterobject.o Objects/listobject.o Objects/longobject.o Objects/dictobject.o Objects/odictobject.o Objects/memoryobject.o Objects/methodobject.o Objects/moduleobject.o Objects/namespaceobject.o Objects/object.o Objects/obmalloc.o Objects/picklebufobject.o Objects/rangeobject.o Objects/setobject.o Objects/sliceobject.o Objects/structseq.o Objects/tupleobject.o Objects/typeobject.o Objects/typevarobject.o Objects/unicodeobject.o Objects/unicodectype.o Objects/unionobject.o Objects/weakrefobject.o  Python/_warnings.o Python/Python-ast.o Python/Python-tokenize.o Python/asdl.o Python/assemble.o Python/ast.o Python/ast_opt.o Python/ast_unparse.o Python/bltinmodule.o Python/brc.o Python/ceval.o Python/codecs.o Python/codegen.o Python/compile.o Python/context.o Python/critical_section.o Python/crossinterp.o Python/dynamic_annotations.o Python/errors.o Python/flowgraph.o Python/frame.o Python/frozenmain.o Python/future.o Python/gc.o Python/gc_free_threading.o Python/gc_gil.o Python/getargs.o Python/getcompiler.o Python/getcopyright.o Python/getplatform.o Python/getversion.o Python/ceval_gil.o Python/hamt.o Python/hashtable.o Python/import.o Python/importdl.o Python/initconfig.o Python/interpconfig.o Python/instrumentation.o Python/instruction_sequence.o Python/intrinsics.o Python/jit.o Python/legacy_tracing.o Python/lock.o Python/marshal.o Python/modsupport.o Python/mysnprintf.o Python/mystrtoul.o Python/object_stack.o Python/optimizer.o Python/optimizer_analysis.o Python/optimizer_symbols.o Python/parking_lot.o Python/pathconfig.o Python/preconfig.o Python/pyarena.o Python/pyctype.o Python/pyfpe.o Python/pyhash.o Python/pylifecycle.o Python/pymath.o Python/pystate.o Python/pythonrun.o Python/pytime.o Python/qsbr.o Python/bootstrap_hash.o Python/specialize.o Python/structmember.o Python/symtable.o Python/sysmodule.o Python/thread.o Python/traceback.o Python/tracemalloc.o Python/uniqueid.o Python/getopt.o Python/pystrcmp.o Python/pystrtod.o Python/pystrhex.o Python/dtoa.o Python/formatter_unicode.o Python/fileutils.o Python/suggestions.o Python/perf_trampoline.o Python/perf_jit_trampoline.o Python/dynload_shlib.o     Modules/config.o Modules/main.o Modules/gcmodule.o Modules/atexitmodule.o  Modules/faulthandler.o  Modules/posixmodule.o  Modules/signalmodule.o  Modules/_tracemalloc.o  Modules/_suggestions.o  Modules/_codecsmodule.o  Modules/_collectionsmodule.o  Modules/errnomodule.o  Modules/_io/_iomodule.o Modules/_io/iobase.o Modules/_io/fileio.o Modules/_io/bytesio.o Modules/_io/bufferedio.o Modules/_io/textio.o Modules/_io/stringio.o  Modules/itertoolsmodule.o  Modules/_sre/sre.o  Modules/_sysconfig.o  Modules/_threadmodule.o  Modules/timemodule.o  Modules/_typingmodule.o  Modules/_weakref.o  Modules/_abc.o  Modules/_functoolsmodule.o  Modules/_localemodule.o  Modules/_opcode.o  Modules/_operator.o  Modules/_stat.o  Modules/symtablemodule.o  Modules/pwdmodule.o -ldl  -llog                           -lm
./Programs/_freeze_module getpath ./Modules/getpath.py Python/frozen_modules/getpath.h
error: /data/local/tmp/develop/cpython314/Programs/_freeze_module: Android only supports position-independent executables (-fPIE)
Makefile:1709: recipe for target 'Python/frozen_modules/getpath.h' failed
make: *** [Python/frozen_modules/getpath.h] Error 1


To fix that error execute these commands:

rm ./Programs/_freeze_module  

gcc     -o Programs/_freeze_module Programs/_freeze_module.o Modules/getpath_noop.o Modules/getbuildinfo.o Parser/token.o  Parser/pegen.o Parser/pegen_errors.o Parser/action_helpers.o Parser/parser.o Parser/string_parser.o Parser/peg_api.o Parser/lexer/buffer.o Parser/lexer/lexer.o Parser/lexer/state.o Parser/tokenizer/file_tokenizer.o Parser/tokenizer/readline_tokenizer.o Parser/tokenizer/string_tokenizer.o Parser/tokenizer/utf8_tokenizer.o Parser/tokenizer/helpers.o Parser/myreadline.o Objects/abstract.o Objects/boolobject.o Objects/bytes_methods.o Objects/bytearrayobject.o Objects/bytesobject.o Objects/call.o Objects/capsule.o Objects/cellobject.o Objects/classobject.o Objects/codeobject.o Objects/complexobject.o Objects/descrobject.o Objects/enumobject.o Objects/exceptions.o Objects/genericaliasobject.o Objects/genobject.o Objects/fileobject.o Objects/floatobject.o Objects/frameobject.o Objects/funcobject.o Objects/iterobject.o Objects/listobject.o Objects/longobject.o Objects/dictobject.o Objects/odictobject.o Objects/memoryobject.o Objects/methodobject.o Objects/moduleobject.o Objects/namespaceobject.o Objects/object.o Objects/obmalloc.o Objects/picklebufobject.o Objects/rangeobject.o Objects/setobject.o Objects/sliceobject.o Objects/structseq.o Objects/tupleobject.o Objects/typeobject.o Objects/typevarobject.o Objects/unicodeobject.o Objects/unicodectype.o Objects/unionobject.o Objects/weakrefobject.o  Python/_warnings.o Python/Python-ast.o Python/Python-tokenize.o Python/asdl.o Python/assemble.o Python/ast.o Python/ast_opt.o Python/ast_unparse.o Python/bltinmodule.o Python/brc.o Python/ceval.o Python/codecs.o Python/codegen.o Python/compile.o Python/context.o Python/critical_section.o Python/crossinterp.o Python/dynamic_annotations.o Python/errors.o Python/flowgraph.o Python/frame.o Python/frozenmain.o Python/future.o Python/gc.o Python/gc_free_threading.o Python/gc_gil.o Python/getargs.o Python/getcompiler.o Python/getcopyright.o Python/getplatform.o Python/getversion.o Python/ceval_gil.o Python/hamt.o Python/hashtable.o Python/import.o Python/importdl.o Python/initconfig.o Python/interpconfig.o Python/instrumentation.o Python/instruction_sequence.o Python/intrinsics.o Python/jit.o Python/legacy_tracing.o Python/lock.o Python/marshal.o Python/modsupport.o Python/mysnprintf.o Python/mystrtoul.o Python/object_stack.o Python/optimizer.o Python/optimizer_analysis.o Python/optimizer_symbols.o Python/parking_lot.o Python/pathconfig.o Python/preconfig.o Python/pyarena.o Python/pyctype.o Python/pyfpe.o Python/pyhash.o Python/pylifecycle.o Python/pymath.o Python/pystate.o Python/pythonrun.o Python/pytime.o Python/qsbr.o Python/bootstrap_hash.o Python/specialize.o Python/structmember.o Python/symtable.o Python/sysmodule.o Python/thread.o Python/traceback.o Python/tracemalloc.o Python/uniqueid.o Python/getopt.o Python/pystrcmp.o Python/pystrtod.o Python/pystrhex.o Python/dtoa.o Python/formatter_unicode.o Python/fileutils.o Python/suggestions.o Python/perf_trampoline.o Python/perf_jit_trampoline.o Python/dynload_shlib.o     Modules/config.o Modules/main.o Modules/gcmodule.o Modules/atexitmodule.o  Modules/faulthandler.o  Modules/posixmodule.o  Modules/signalmodule.o  Modules/_tracemalloc.o  Modules/_suggestions.o  Modules/_codecsmodule.o  Modules/_collectionsmodule.o  Modules/errnomodule.o  Modules/_io/_iomodule.o Modules/_io/iobase.o Modules/_io/fileio.o Modules/_io/bytesio.o Modules/_io/bufferedio.o Modules/_io/textio.o Modules/_io/stringio.o  Modules/itertoolsmodule.o  Modules/_sre/sre.o  Modules/_sysconfig.o  Modules/_threadmodule.o  Modules/timemodule.o  Modules/_typingmodule.o  Modules/_weakref.o  Modules/_abc.o  Modules/_functoolsmodule.o  Modules/_localemodule.o  Modules/_opcode.o  Modules/_operator.o  Modules/_stat.o  Modules/symtablemodule.o  Modules/pwdmodule.o -ldl  -llog -lm -pie -fPIE 


Then restart make to continue the build:

make


The same error occurs for the binaries

./_bootstrap_python

and

python

To fix it, use the same approach.


Notes:

Be aware that there is a bug in the customization script in the Magisk Module with the GCC Toolchain version 1.0.0 :

The customization script does not configure the execution permission for some of the binaries in the module. To fix that issue, execute this command after installing the Magisk Module and rebooting the phone:

su - -c "chmod 755 /data/adb/modules/gcc_on_android/system/usr/share/gcc/aarch64-linux-android/bin/*


To create a python binary that only needs the standard Android OS libraries, execute this command after creating the "original" python binary:

gcc -Xlinker -export-dynamic -o python_static  Programs/python.o  -ldl  -llog -lm -fPIE -pie libpython3.14.a  


To check the result use these commmands.

┌root@localhost:/data/local/tmp/develop/cpython314
└─# ls -l python_static
-rwxr-xr-x 1 root root 43598608 2025-04-10 18:36 python_static
┌root@localhost:/data/local/tmp/develop/cpython314
└─#

root@localhost:/data/local/tmp/develop/cpython314

└─# ldd $PWD/python_static
    linux-vdso.so.1 => [vdso] (0x7600ba6000)
    libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x75fbef1000)
    liblog.so => /system/lib64/liblog.so (0x75fbf10000)
    libm.so => /apex/com.android.runtime/lib64/bionic/libm.so (0x75fbe85000)
    libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x75f9459000)
    libc++.so => /system/lib64/libc++.so (0x75f8c5b000)
┌root@localhost:/data/local/tmp/develop/cpython314
└─#



History of this entry

10.04.2025

added the missing options "-fPIE -pe" to the environment variable CFLAGS
added the info about the error in the customization script in the Magisk Module with the GCC toolchain


08.04.2025

initial release






Examples for compiling programs using the new gcc toolchain in Android


Note:

The "new gcc toolchain" is the gcc toolchain described in this section How to compile a C or C++ program for Android in Android with gcc without root access

The examples below assume that the directory with gcc and the other tools from the gcc toolchain is available via PATH variable.



How to compile pigz in Android using the new gcc toolchain on the phone


How to compile pigz in Android using the new gcc toolchain on the phone

Source:
http://zlib.net/pigz


1. Download the source code for pigz

wget http://zlib.net/pigz/pigz-2.8.tar.gz


2. Unpack the tar file

tar -xf pigz-2.8.tar.gz

cd pigz-2.8


3. Create the binary

make


----

History of this entry

31.05.2026

initial release


----



How to compile the ncurses library in Android using the new gcc toolchain on the phone


How to compile the ncurses library in Android using the new gcc toolchain on the phone

Source:  https://www.gnu.org/software/ncurses/


Download and unpack the source files for ncurses:

wget https://ftp.gnu.org/gnu/ncurses/ncurses-6.3.tar.gz
tar -xzf ncurses-6.3.tar.gz
cd ncurses-6.3/



Use ./configure to create the make files:

./configure --prefix=/data/local/tmp/sysroot_test

and build the library:

make

Use

make install

to intall the library.


----

History of this entry

31.05.2026

initial release


----



How to compile bvi in Android using the new gcc toolchain on the phone


How to compile bvi in Android using the new gcc toolchain on the phone

Source:  https://bvi.sourceforge.net/


Download the source for bvi:

wget http://sourceforge.net/projects/bvi/files/bvi/1.4.2/bvi-1.4.2.src.tar.gz/download -O bvi-1.4.2.src.tar.gz

and unpack the tar file

tar -xf bvi-1.4.2.src.tar.gz
cd bvi-1.4.2



Create the make file

./configure --prefix=/data/local/tmp/sysroot_test CFLAGS="-DHAVE_CONFIG_H -Drpl_malloc=malloc -Drpl_realloc=realloc -Drpl_free=free"


And create the binary:

make
 


----
 
History of this entry

31.05.2026

initial release


----



Examples for compiling programs using the clang toolchain in Android



Note:

To compile more complex tools such as bash, perl, python, nano, etc you will need the libraries from the GitHub repository https://github.com/bnsmb/libraries-and-include-files-for-Android-on-arm64-CPUs on the phone (see the General hints above)



How to compile pigz in Android using the clang19 toolchain on the phone



How to compile pigz in Android using the clang19 toolchain on the phone

Source:
http://zlib.net/pigz


1. Init the clang19 toolchain if not already done:

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



2. Download the source code for pigz

wget http://zlib.net/pigz/pigz-2.8.tar.gz


3. Unpack the tar file

tar -xf pigz-2.8.tar.gz

cd pigz-2.8


4. Correct the make file for pigz 

cp Makefile  Makefile.org

sed -i -e "s#CC=gcc#CC=$CC#g" -e "s#CFLAGS=#CFLAGS=${CFLAGS} #g" -e "s#LDFLAGS=#LDFLAGS=$LDFLAGS #g"  Makefile 

# Check the result

diff Makefile  Makefile.org

5. Create the binary

make



History of this entry

19.04.2026

initial release





How to compile the ncurses library in Android using the clang19 toolchain on the phone



How to compile the ncurses library in Android using the clang19 toolchain on the phone

Source:  https://www.gnu.org/software/ncurses/


Init the clang19 toolchain if not already done:

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


Download and unpack the source files for ncurses:

wget https://ftp.gnu.org/gnu/ncurses/ncurses-6.3.tar.gz
tar -xzf ncurses-6.3.tar.gz
cd ncurses-6.3/



Use ./configure to create the make files:

./configure

and build the library:

make




History of this entry

18.04.2026

initial release





How to compile bvi in Android using the clang19 toolchain on the phone



How to compile bvi in Android using the clang19 toolchain on the phone

Source:  https://bvi.sourceforge.net/


Init the clang19 toolchain if not already done:

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



Download the source for bvi:

wget http://sourceforge.net/projects/bvi/files/bvi/1.4.2/bvi-1.4.2.src.tar.gz/download -O bvi-1.4.2.src.tar.gz

and unpack the tar file

tar -xf bvi-1.4.2.src.tar.gz
cd bvi-1.4.2



Create the make file

./configure


And create the binary:

make


Note:

To create a statically linked binary use the following commands

./configure LDFLAGS="$LDFLAGS -static" && make


 

History of this entry

18.04.2026

initial release





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


URL: https://xdaforums.com/t/guide-how-to-compile-perl-in-android-with-the-clang19-toolchain-on-the-phone.4765540/


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

Init the clang19 toolchain if not already done:

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


Then download the source files for Perl from here: https://www.cpan.org/src/5.0/

The latest stable release in Oct. 2025 is:

https://www.cpan.org/src/5.0/perl-5.42.0.tar.gz


The latest development release in Oct. 2025 is:

https://www.cpan.org/src/5.0/perl-5.43.3.tar.gz


(Perl releases with an odd version are unstable development releases)


Copy the tar file to the phone, and unpack it in the directory /data/local/tmp/ (or a sub directory of this directory).

Init the clang19 toolchain (using the default API version 31):

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


Create the wrapper scripts necessary to compile Perl with the clang19 toolchain if they do not yet exist:

[ !  -x /data/local/tmp/sysroot/usr/bin/cc  ]  &&  \
   echo '/data/local/tmp/sysroot/usr/clang19/bin/clang $CFLAGS $LDFLAGS $*' >/data/local/tmp/sysroot/usr/bin/cc  && \
   chmod 755 /data/local/tmp/sysroot/usr/bin/cc

[ ! -x /data/local/tmp/sysroot/usr/bin/cpp ]  &&  \
  echo '/data/local/tmp/sysroot/usr/clang19/bin/clang-cpp $CFLAGS $CPPFLAGS $*' > /data/local/tmp/sysroot/usr/bin/cpp && \
  chmod 755 /data/local/tmp/sysroot/usr/bin/cpp


/tmp/develop/sysroot/usr/lib ls


To compile Perl some other libraries are required. Either compile these libraries yourself or download the pre compiled libraries for example from this GitHub repository:

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

and install the files from that repository in the directory /data/local/tmp/develop/sysroot/usr/:

mkdir -p /data/local/tmp/develop

cd /data/local/tmp/develop


# Note: the git executable is part of the clang19 toolchain

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

mv libraries-and-include-files-for-Android-on-arm64-CPUs/sysroot/ . 


# add the directories in /data/local/tmp/develop/sysroot/usr to the clang19 environment variables
#
source /data/local/tmp/sysroot/bin/init_clang19_env 


Now change the working directory to the directory with the source code for Perl an execute the script ./Configure from the Perl source code with these parameters to prepare the Perl source code for compiling Perl in Android:


LOCALE_CONFIG="-DNO_LOCALE -DNO_LOCALE_CTYPE -DNO_LOCALE_NUMERIC -DNO_LOCALE_COLLATE -DNO_LOCALE_TIME -DNO_LOCALE_MESSAGES -DNO_LOCALE_MONETARY -DNO_LOCALE_ADDRESS -DNO_LOCALE_IDENTIFICATION  -DNO_LOCALE_MEASUREMENT -DNO_LOCALE_PAPER  -DNO_LOCALE_TELEPHONE -DNO_LOCALE_NAME -DNO_LOCALE_SYNTAX -DNO_LOCALE_TOD"


./Configure -Dprefix="/data/local/tmp/sysroot/usr"  -Dsysroot="${SYSROOT}"  \
   -Dccflags=" -fPIE -pie --std=gnu99 --sysroot=
${SYSROOT} ${CFLAGS}  -Wno-implicit-function-declaration -Wno-int-conversion -DHAS_SHMAT_PROTOTYPE ${LOCALE_CONFIG} "  \
   -Uuselocale \
   -Dldflags="-pie ${LDFLAGS} " \
   -Dnoextensions=Locale


Notes:

There might be a setting that includes all the "-DNO_LOCALE_*" definitions, but I haven't found it yet .. and at least the command above works to compile Perl without locale support.

/data/local/tmp/sysroot/usr is the target directory for the compiled Perl; this can be any directory on a filesystem formatted with ext3 or better


The variable ${SYSROOT} in the parameter for the script ./Configure is the sysroot directory in the Android NDK used; this is /data/local/tmp/sysroot/usr/ndk/r27d/sysroot in the clang19 toolchain (as of 26.10.2025; the variable SYSROOT is defined in the init script for the clang19 toolchain).


./Configure is an interactive script and asks a lot of questions -- for most of them the default answer is okay - there are only a few exceptions:


The libraries libpthread and libgdbm_compat are not necessary in Android. Therefore, answer the question

What libraries to use? [-lpthread -lgdbm -ldl -lm -lcrypt -lc -lgdbm_compat]

with

-lgdbm -ldl -lm -lcrypt -lc


Note: To create a binary and libraries that only need the standard Android OS libraries, replace the additional dynamic libraries with static libraries here, e.g. enter:

/data/local/tmp/develop/sysroot/usr/lib/libgdbm.a /data/local/tmp/develop/sysroot/usr/lib/libcrypt.a -ldl -lm -lc


The hints for Android in the source code for Perl 5.42 are written for an earlier API version. Therefore, some libc functions that are missing in Android according to the hints are now available in the standard libraries from Android.

These functions are defined in the libc from the Android API version 31:

getnetbyaddr
getnetbyname
getprotobyname
getprotobynumber
getservent_r

The question “Keep the recommended value?” from the ./Configure script for these functions must be answered with n for no.

The other questions of the Configure script can be answered with the default value but it's recommended to use absolute path names for the directories.


When done, start the compile process using the command

make -j$( $nproc )

The result should look like this:

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/perl-5.43.3 $ ls -l perl
-rwxr-xr-x 1 shell shell 4326352 2025-10-27 11:48 perl
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/perl-5.43.3 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/perl-5.43.3 $ file perl
perl: ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), for Android 31, built by NDK r27d (13750724), not stripped
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/perl-5.43.3 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/perl-5.43.3 $ ldd $PWD/perl
    linux-vdso.so.1 => [vdso] (0x78816e7000)
    libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x787c06e000)
    libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x787e0f4000)
    libm.so => /apex/com.android.runtime/lib64/bionic/libm.so (0x787e101000)
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/perl-5.43.3 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/perl-5.43.3 $ ./perl --version

This is perl 5, version 43, subversion 3 (v5.43.3) built for aarch64-linux-android

Copyright 1987-2025, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at https://www.perl.org/, the Perl Home Page.

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/perl-5.43.3 $


Troubleshooting

If you get an error message like this:

CANNOT LINK EXECUTABLE "./try": library "libgdbm.so.3" not found: needed by main executable
The program compiled OK, but exited with status 1.

one of the used libraries but was not found when executing the test program. To fix the error, add the directory with the missing library to the environment variable LD_LIBRARY_PATH before starting the configure script.





History of this entry

28.10.2025

fix some minor errors

20.01.2025

initial release



 

How to compile jq in Android using the clang19 toolchain on the phone


URL: https://xdaforums.com/t/guide-how-to-compile-jq-in-android-using-the-clang19-toolchain-on-the-phone.4714895/


How to compile jq in Android using the clang19 toolchain on the phone

"jq is a lightweight and flexible command-line JSON processor. " -- see https://jqlang.github.io/jq/ 


This Howto shows the necessary commands to compile jq on a phone or tablet running Android using the clang19 toolchain.

The following instructions assume that the clang19 toolchain has been installed, configured, and initialized. No additional libraries are necessary to compile jq.

The instructions can be used as template for compiling other tools with the clang19 toolchain.


Instructions to compile jq with the clang19 toolchain


Init the clang19 toolchain if not already done:

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


Download the source code for jq to the phone

mdkir -p /data/local/tmp/develop


cd /data/local/tmp/develop

wget https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-1.7.1.tar.gz


and unpack the tar archive:

tar -xf jq-1.7.1.tar.gz  


Change the working directory to the directory with the jq source code

cd jq-1.7.1


and execute the ./configure script to prepare the source code:

Note: ax_pthread_ok=no -> do not use the library libpthread.so -- this library is not necessary in Android
 
ax_pthread_ok=no ./configure --prefix=/data/local/tmp/sysroot/usr --disable-valgrind --disable-docs


After ./configure finished, copy the necessary runtime files into the source directories (this must be done again after a "make clean"; this step is normally not necessary to compile a tool with the clang19 toolchain):

cp ${SYSROOT_LIB_DIR}/${API}/crt*o .
cp ${SYSROOT_LIB_DIR}/${API}/crt*o ./src
cp ${SYSROOT_LIB_DIR}/${API}/crt*.o ./modules/oniguruma/src


and start the compile process:

make


Then check the result:

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $ ls -l jq
-rwxrwxrwx 1 shell shell 1199560 2025-01-22 16:21 jq
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $ file jq
jq: ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), for Android 31, built by NDK r27b (12297006), not stripped
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $ ldd $PWD/jq
    linux-vdso.so.1 => [vdso] (0x7b9fcb6000)
    libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x7b9ca18000)
    libm.so => /apex/com.android.runtime/lib64/bionic/libm.so (0x7b9e883000)
    libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x7b9e85e000)
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $ ./jq --version
jq-1.7.1
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $



Optional, remove the symbols from the jq binary to save some space:

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $ file jq
jq: ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), for Android 31, built by NDK r27b (12297006), not stripped
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $ ls -lh jq
-rwxrwxrwx 1 shell shell 1.1M 2025-01-22 16:21 jq
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $ $STRIP --strip-all jq
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $ ls -lh jq
-rwxrwxrwx 1 shell shell 1.0M 2025-01-22 16:23 jq
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $ file jq
jq: ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), for Android 31, built by NDK r27b (12297006), stripped
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $ ./jq --version
jq-1.7.1
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $


[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/jq-1.7.1 $


Notes

It's recommended to check for existing patches for a tool in the repositories for Termux before compiling it; the patches from Termux are available here:

https://github.com/termux/termux-packages/tree/master/packages

(Note: As of 22.01.2025 there are no patches for jq in the Termux repositories)

see the section How to compile bash in Android with the clang19 toolchain on the phone for example instructions how to apply patches from Termux.

jq can also be compiled as a statically linked binary with the configure script option --enable-all-static. This works, but note that statically linked binaries in Android cannot perform hostname resolution via DNS.



Trouble Shooting

In the event of an error when executing the new jq binary, use the debugger gdb (which is also part of the clang19 toolchain) to find the cause of the error:

gdb ./jq

(do not remove the symbols from the binary in this case)

see https://sourceware.org/gdb/current/onlinedocs/gdb.html for the documentation for gdb.




History of this entry

22.01.2025

initial release





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


URL: https://xdaforums.com/t/guide-how-to-compile-nano-in-android-with-the-clang19-toolchain-on-the-phone.4714967/


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

nano (https://www.nano-editor.org/) is a full screen editor for those wo do not like vi.


This Howto shows the necessary commands to compile nano on a phone or tablet running Android using the clang19 toolchain.

The following instructions assume that the clang19 toolchain has been installed, configured, and initialized. The libraries and header files required to compile nano (libz and libncursesw) must be available on the phone.

The instructions can be used as template for compiling other tools with the clang19 toolchain.

Init the clang19 toolchain if not already done:

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


First download the tar file with the nano sources and unpack the tar file on the phone:

mkdir /data/local/tmp/develop
cd /data/local/tmp/develop

wget https://www.nano-editor.org/dist/v8/nano-8.3.tar.xz


xz -d nano-8.3.tar.xz      
tar -xf nano-8.3.tar


It's recommended to apply the patches from Termux instead of patching the source code manually.

The patches for nano from the Termux repositories can be downloaded from here:

https://github.com/termux/termux-packages/tree/master/packages/nano


To apply the patches create a directory for the patches for nano:

cd nano-8.3
mkdir patches
cd patches


and copy the patches to the directory ./patches , example:

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3/patches $ ls -l
total 12
-rw-rw-rw- 1 shell shell 1501 2025-01-23 13:41 build.sh
-rw-rw-rw- 1 shell shell  733 2025-01-23 13:41 src-files.c.patch
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3/patches $


Then replace the variable TERMUX_PREFIX with the "new" root directory in all patches ( /data/local/tmp/sysroot in this example):

sed -i -e "s#@TERMUX_PREFIX@#/data/local/tmp/sysroot#g" *



You can also manually correct the patch files if necessary.


Next create the script to apply the patches using the script create_patch_script.sh (the script create_patch_script.sh is part of the clang19 toolchain):

create_patch_script.sh


The script create_patch_script.sh creates the script apply_patches.sh in the current directory with instructions to apply all *.patch files in the current directory.


Example output:

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3/patches $ create_patch_script.sh

Processing the patch "src-files.c.patch" ...
The patch is for the file "src/files.c"

Creating the patch script in "/data/local/tmp/develop/nano-8.3/patches/apply_patches.sh" ...

-rwxr-xr-x 1 shell shell 259 2025-01-23 13:05 /data/local/tmp/develop/nano-8.3/patches/apply_patches.sh


Then execute the script ./apply_patches.sh to apply the patches to the source files:

./apply_patches.sh


Example output:

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3/patches $ ./apply_patches.sh

*** Patch: src-files.c.patch
patching ../src/files.c
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3/patches $


Now execute the ./configure script to prepare the source code. To get the necessary options for  the ./configure script, check the output of the command

./configure --help

It's also recommended to check the contents of the script build.sh in the patch directory for the tool compile in the Termux repositories


#
# the following compiler flags are necessary to compile nano with clang 19 (they are also necessary to compile a lot of other tools with clang 19)
#
# If the build fails with an error like "undeclared identifier 'error'" add the definition "-DGNULIB_LIBPOSIX" to the CFLAGS
#
CFLAGS="$CFLAGS -Wno-implicit-function-declaration -Wno-int-conversion"

# create a static binary so that the nano executable runs on any Android OS
#
LDFLAGS="$LDFLAGS -static"

./configure --prefix=/data/local/tmp/sysroot/usr --disable-nls --enable-utf8


And start the compile process using make

make -j$( nproc)


When make is finished, check the result:

[clang19 toolchain] 130|ASUS_I006D:/data/local/tmp/develop/nano-8.3 $ ls -l src/nano
-rwxrwxrwx 1 shell shell 3389312 2025-01-23 13:50 src/nano
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $ file src/nano
src/nano: ELF executable, 64-bit LSB arm64, static, for Android 31, built by NDK r27b (12297006), not stripped
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $

# Note: "unexpected e_type 2" -> this is a statically linked executable
#
[clang19 toolchain] 1|ASUS_I006D:/data/local/tmp/develop/nano-8.3 $ ldd $PWD/src/nano
error: "/data/local/tmp/develop/nano-8.3/src/nano" has unexpected e_type: 2
[clang19 toolchain] 1|ASUS_I006D:/data/local/tmp/develop/nano-8.3 $

clang19 toolchain] 1|ASUS_I006D:/data/local/tmp/develop/nano-8.3 $ src/nano --version
 GNU nano, version 8.3
 (C) 2024 the Free Software Foundation and various contributors
 Compiled options: --disable-libmagic --disable-nls --enable-utf8
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $



Optionally, you can use llvm-strip to remove the symbols from the nano binary using llvm-strip to save some space:


[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $ ls -lh src/nano
-rwxrwxrwx 1 shell shell 3.2M 2025-01-23 13:50 src/nano
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $ file src/nano
src/nano: ELF executable, 64-bit LSB arm64, static, for Android 31, built by NDK r27b (12297006), not stripped
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $ $STRIP --strip-all src/nano
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $ ls -lh src/nano

-rwxrwxrwx 1 shell shell 1.2M 2025-01-23 13:52 src/nano
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $ file src/nano
src/nano: ELF executable, 64-bit LSB arm64, static, for Android 31, built by NDK r27b (12297006), stripped
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $ src/nano --version
 GNU nano, version 8.3
 (C) 2024 the Free Software Foundation and various contributors
 Compiled options: --disable-libmagic --disable-nls --enable-utf8
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/nano-8.3 $


Trouble Shooting

In the event of an error when executing the new nano binary, use the debugger gdb (which is also part of the clang19 toolchain) to find the cause of the error:

gdb ./nano

(do not remove the symbols from the binary in this case)

see https://sourceware.org/gdb/current/onlinedocs/gdb.html for the documentation for gdb.





Update 01.02.2025

There is now a new version of the script create_patch_script.sh available:

create_patch_script.sh

The previous version of the script could not handle patch files for multiple files properly. Therefore, I recommend using this new version of the script



History of this entry

01.02.2025

added info about the new version of the script create_patch_script.sh  


23.01.2025

initial release





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



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

This Howto shows the necessary commands to compile bash on a phone or tablet running Android using the clang19 toolchain.

The following instructions assume that the clang19 toolchain has been installed, configured, and initialized and that the libraries required for bash are available in the directory /data/local/tmp/develop/usr/lib.

The instructions can be used as template for compiling other tools with the clang19 toolchain.



Instructions to compile bash with the clang19 toolchain

Init the clang19 toolchain if not already done:

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


First download the git repository for bash (alternative: Download and unpack the ZIP file with the source code)

cd /data/local/tmp/develop
git_no_ssl_verify  clone https://github.com/bminor/bash.git


Example
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop $ git_no_ssl_verify  clone https://github.com/bminor/bash.git
Cloning into 'bash'...
remote: Enumerating objects: 43627, done.
remote: Counting objects: 100% (5472/5472), done.
remote: Compressing objects: 100% (655/655), done.
remote: Total 43627 (delta 5052), reused 4819 (delta 4817), pack-reused 38155 (from 2)
Receiving objects: 100% (43627/43627), 281.23 MiB | 3.40 MiB/s, done.
Resolving deltas: 100% (37785/37785), done.
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop $



It's recommended to apply the patches from Termux instead of patching the source code manually.

The patches for bash from the Termux repositories can be downloaded from here:

https://github.com/termux/termux-packages/tree/master/packages/bash

To apply the patches create a directory for the patches for bash:

cd bash
mkdir patches
cd patches

and copy the patches to the directory ./patches .

Then replace the variable TERMUX_PREFIX with the "new" root directory in all patches ( /data/local/tmp/sysroot in this example):

sed -i -e "s#@TERMUX_PREFIX@#/data/local/tmp/sysroot#g" *


You can also manually correct the patch files if necessary.


When done, create the script to apply the patches using this command (the script create_patch_script.sh is part of the clang19 toolchain):

create_patch_script.sh

Example
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash/patches $ create_patch_script.sh

Processing the patch "config-top.h.patch" ...
The patch is for the file "config-top.h"

Processing the patch "error.c.patch" ...
The patch is for the file "error.c"

Processing the patch "examples-loadables-fdflags.c.patch" ...
The patch is for the file "examples/loadables/fdflags.c"

Processing the patch "examples-loadables-getconf.c.patch" ...
The patch is for the file "examples/loadables/getconf.c"

Processing the patch "lib-malloc-stats.c.patch" ...
The patch is for the file "lib/malloc/stats.c"

Processing the patch "lib-malloc-table.c.patch" ...
The patch is for the file "lib/malloc/table.c"

Processing the patch "lib-malloc-trace.c.patch" ...
The patch is for the file "lib/malloc/trace.c"

Processing the patch "lib-readline-complete.c.patch" ...
The patch is for the file "lib/readline/complete.c"

Processing the patch "lib-readline-rlconf.h.patch" ...
The patch is for the file "lib/readline/rlconf.h"

Processing the patch "lib-readline-util.c.patch" ...
The patch is for the file "lib/readline/util.c"

Processing the patch "lib-sh-tmpfile.c.patch" ...
The patch is for the file "lib/sh/tmpfile.c"

Processing the patch "pathnames.h.in.patch" ...
The patch is for the file "pathnames.h.in"

Processing the patch "shell.c.patch" ...
The patch is for the file "shell.c"

Creating the patch script in "/data/local/tmp/develop/bash/patches/apply_patches.sh" ...

-rwxr-xr-x 1 shell shell 2501 2025-01-22 11:15 /data/local/tmp/develop/bash/patches/apply_patches.sh

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash/patches $



and apply the patches to the source code for bash (the script apply_patches.sh is created by the script create_patch_script.sh)

./apply_patches.sh


Example
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash/patches $ ./apply_patches.sh

*** Patch: config-top.h.patch
patching ../config-top.h

*** Patch: error.c.patch
patching ../error.c

*** Patch: examples-loadables-fdflags.c.patch
patching ../examples/loadables/fdflags.c

*** Patch: examples-loadables-getconf.c.patch
patching ../examples/loadables/getconf.c

*** Patch: lib-malloc-stats.c.patch
patching ../lib/malloc/stats.c

*** Patch: lib-malloc-table.c.patch
patching ../lib/malloc/table.c

*** Patch: lib-malloc-trace.c.patch
patching ../lib/malloc/trace.c

*** Patch: lib-readline-complete.c.patch
patching ../lib/readline/complete.c

*** Patch: lib-readline-rlconf.h.patch
patching ../lib/readline/rlconf.h

*** Patch: lib-readline-util.c.patch
patching ../lib/readline/util.c

*** Patch: lib-sh-tmpfile.c.patch
patching ../lib/sh/tmpfile.c

*** Patch: pathnames.h.in.patch
patching ../pathnames.h.in

*** Patch: shell.c.patch
patching ../shell.c
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash/patches $


# exit the directory with the patches
#
cd ..




Now prepare the source code for bash using the configure script.

(The configure options used (CONFIGURE_OPTIONS) are copied from the build script from Termux: https://github.com/termux/termux-packages/blob/master/packages/bash/build.sh)

CONFIGURE_OPTIONS="
--enable-multibyte --without-bash-malloc --with-installed-readline
bash_cv_job_control_missing=present"
bash_cv_sys_siglist=yes"
bash_cv_func_sigsetjmp=present"
bash_cv_unusable_rtsigs=no"
ac_cv_func_mbsnrtowcs=no"
bash_cv_dev_fd=whacky"
bash_cv_getcwd_malloc=yes"

# the following compiler flags are necessary to compile bash with clang 19 (they are also necessary to compile a lot of other tools with clang 19)
#
export CFLAGS="${CFLAGS} -Wno-implicit-function-declaration -Wno-int-conversion"   

# prepare the source code for creation of a statically linked executable (the dynamically linked executable can be build, but fails with a Segmentation fault at startup)
#
./configure
--enable-static-link  ${CONFIGURE_OPTIONS} 


When the ./configure script is done, start the compile proccess for bash :

make


make will most probably fail with this error:

...
/data/local/tmp/sysroot/usr/clang19/bin/clang -L./builtins -L./lib/readline -L./lib/readline -L./lib/glob -L./lib/tilde  -L./lib/sh  -L/data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/31 -L/data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android -L/data/local/tmp/develop/sysroot/usr/lib -B/data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/31/ --sysroot=/data/local/tmp/sysroot/usr/ndk/r27b/sysroot -lc   -rdynamic -I/data/local/tmp/sysroot/usr/clang19/include -I/data/local/tmp/sysroot/usr/ndk/r27b/include -I/data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/include/aarch64-linux-android -I/data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/include -I/data/local/tmp/develop/sysroot/usr/include --sysroot=/data/local/tmp/sysroot/usr/ndk/r27b/sysroot -Wno-implicit-function-declaration -Wno-int-conversion  -static -o bash shell.o eval.o y.tab.o general.o make_cmd.o print_cmd.o  dispose_cmd.o execute_cmd.o variables.o copy_cmd.o error.o expr.o flags.o jobs.o subst.o hashcmd.o hashlib.o mailcheck.o trap.o input.o unwind_prot.o pathexp.o sig.o test.o version.o alias.o array.o arrayfunc.o assoc.o braces.o bracecomp.o bashhist.o bashline.o  list.o stringlib.o locale.o findcmd.o redir.o pcomplete.o pcomplib.o syntax.o xmalloc.o  -lbuiltins -lglob -lsh -lreadline -lhistory -lncurses -ltilde   /data/local/tmp/develop/sysroot/usr/lib/libiconv.so -Wl,-rpath -Wl,/data/local/tmp/develop/sysroot/usr/lib 
clang: warning: argument unused during compilation: '-rdynamic' [-Wunused-command-line-argument]
ld.lld: error: attempted static link of dynamic object /data/local/tmp/develop/sysroot/usr/lib/libiconv.so
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Makefile:595: bash] Error 1
    0m58.46s real     0m17.09s user     0m12.30s system
[clang19 toolchain] 2|ASUS_I006D:/data/local/tmp/develop/bash $


To fix it, link the bash binary manually replacing the dynamic library libconv.so with the static version of the library libiconv.a:

/data/local/tmp/sysroot/usr/clang19/bin/clang -L./builtins -L./lib/readline -L./lib/readline -L./lib/glob -L./lib/tilde  -L./lib/sh  -L/data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/31 -L/data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android -L/data/local/tmp/develop/sysroot/usr/lib -B/data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/lib/aarch64-linux-android/31/ --sysroot=/data/local/tmp/sysroot/usr/ndk/r27b/sysroot -lc   -rdynamic -I/data/local/tmp/sysroot/usr/clang19/include -I/data/local/tmp/sysroot/usr/ndk/r27b/include -I/data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/include/aarch64-linux-android -I/data/local/tmp/sysroot/usr/ndk/r27b/sysroot/usr/include -I/data/local/tmp/develop/sysroot/usr/include --sysroot=/data/local/tmp/sysroot/usr/ndk/r27b/sysroot -Wno-implicit-function-declaration -Wno-int-conversion  -static -o bash shell.o eval.o y.tab.o general.o make_cmd.o print_cmd.o  dispose_cmd.o execute_cmd.o variables.o copy_cmd.o error.o expr.o flags.o jobs.o subst.o hashcmd.o hashlib.o mailcheck.o trap.o input.o unwind_prot.o pathexp.o sig.o test.o version.o alias.o array.o arrayfunc.o assoc.o braces.o bracecomp.o bashhist.o bashline.o  list.o stringlib.o locale.o findcmd.o redir.o pcomplete.o pcomplib.o syntax.o xmalloc.o  -lbuiltins -lglob -lsh -lreadline -lhistory -lncurses -ltilde   /data/local/tmp/develop/sysroot/usr/lib/libiconv.a -Wl,-rpath -Wl,/data/local/tmp/develop/sysroot/usr/lib


Check the result:

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $ ls -l bash
-rwxrwxrwx 1 shell shell 6014704 2025-01-22 13:51 bash
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $ file bash
bash: ELF executable, 64-bit LSB arm64, static, for Android 31, built by NDK r27b (12297006), not stripped
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $ ldd $PWD/bash
error: "/data/local/tmp/develop/bash/bash" has unexpected e_type: 2
[clang19 toolchain] 1|ASUS_I006D:/data/local/tmp/develop/bash $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $ ./bash --version
GNU bash, version 5.2.37(1)-release (aarch64-unknown-linux-gnu)
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $


Optionally, you can use llvm-strip to remove the symbols from the bash binary to save some space:

$STRIP --strip-all ./bash

Example
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $ ls -lh bash
-rwxrwxrwx 1 shell shell 5.7M 2025-01-22 14:25 bash
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $ file bash
bash: ELF executable, 64-bit LSB arm64, static, for Android 31, built by NDK r27b (12297006), not stripped
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $                         

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $ $STRIP --strip-all ./bash
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $ ls -lh bash
-rwxrwxrwx 1 shell shell 3.0M 2025-01-22 14:26 bash
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $ file bash
bash: ELF executable, 64-bit LSB arm64, static, for Android 31, built by NDK r27b (12297006), stripped
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $ ./bash --version
GNU bash, version 5.2.37(1)-release (aarch64-unknown-linux-gnu)
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/bash $




Trouble Shooting

In the event of an error when executing the new bash binary, use the debugger gdb (which is also part of the clang19 toolchain) to find the cause of the error:

gdb ./bash

(do not remove the symbols from the binary in this case)

see https://sourceware.org/gdb/current/onlinedocs/gdb.html for the documentation for gdb.




History of this entry

22.01.2025

initial release





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


URL: https://xdaforums.com/t/guide-how-to-compile-python-using-the-clang19-toolchain.4767178/


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


This guide contains instructions to compile Python on the phone running the Android OS using the clang19 toolchain.


Init the clang19 toolchain if not already done:

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



Then download the source files for Python from here: https://www.python.org/ftp/python/  

The latest stable release in Nov. 2025 is:

https://www.python.org/ftp/python/3.14.0/Python-3.14.0.tgz


The latest development release in Nov. 2025 is:

https://www.python.org/ftp/python/3.15.0/Python-3.15.0a1.tgz


Copy the tar file to the phone, and unpack it in the directory /data/local/tmp/ (or a sub directory of this directory).


Check the patches for Python from Termux and apply them if necessary. The patches for Python from Termux are available here:

https://github.com/termux/termux-packages/tree/master/packages/python


Then init the clang19 toolchain (using the default API version 31):

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


The instructions below to compile Python assume that the additional libraries and include files needed to compile Python are in the directory tree /data/local/tmp/sysroot.

If they do not yet exist on the phone, use these commands to download the libraries to the phone (the git executable is part of the clang19 toolchain):

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


Then add the directories in /data/local/tmp/develop/sysroot to the environment variables used in the clang19 toolchain:

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


Next setup the environment for building Python and execute the configure script for Python:


export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/local/tmp/develop/sysroot/usr/lib

export CFLAGS="$CFLAGS -D__ANDROID_API__=31 -O3  -Wno-implicit-function-declaration -Wno-int-conversion "
export CPPFLAGS="$CFLAGS"

export TARGET_ROOT=/system

export PKG_CONFIG=/data/local/tmp/sysroot/usr/clang19/bin/pkgconf


AC_OPTIONS="
ac_cv_func_shm_unlink=no 
ac_cv_func_shm_open=yes
ac_cv_posix_semaphores_enabled=yes
ac_cv_func_linkat=no
ac_cv_func_faccessat=no 
ac_cv_file__dev_ptc=no
"


# use the static ncurses library
#
LDFLAGS="$LDFLAGS /data/local/tmp/develop/sysroot/usr/lib/libncursesw.a"

CONFIGURE_OPTIONS="
--with-openssl=/data/local/tmp/develop/sysroot/usr
--enable-loadable-sqlite-extensions
--enable-shared 
--enable-pystats 
--with-builtin-hashlib-hashes=md5,sha1,sha2,sha3,blake2,sha256,sha512
--with-tzpath=${TARGET_ROOT}/usr/share/zoneinfo
"

eval ${AC_OPTIONS} ./configure  --prefix=${TARGET_ROOT}/usr  ${CONFIGURE_OPTIONS}

# fix errors in the Makefile created by ./configure
#
echo "Correcting the Makefile ..."

sed -i -e "s/none required//g" Makefile


# Exclude some modules from the build

cat  >Modules/Setup.local <<EOT
*disabled*
_tkinter
_gdbm
_gdbm_compat
_dbm
_posixshmem

EOT


and start the build

make


Check the result:

[clang19 toolchain] 2|ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $ ls -ltr python
-rwxrwxrwx 1 shell shell 7224 2025-11-07 14:41 python
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $ ls -lh python
-rwxrwxrwx 1 shell shell 7.0K 2025-11-07 14:41 python
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $
 
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $ file python
python: ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), for Android 31, built by NDK r27d (13750724), not stripped
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $ LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH ldd $PWD/python
    linux-vdso.so.1 => [vdso] (0x735fce7000)
    libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x735e884000)
    libpython3.15.so.1.0 => /data/local/tmp/develop/Python-3.15.0a1/libpython3.15.so.1.0 (0x735c029000)
    libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x735e81b000)
    liblog.so => /system/lib64/liblog.so (0x735e7e0000)
    libm.so => /apex/com.android.runtime/lib64/bionic/libm.so (0x735e844000)
    libc++.so => /system/lib64/libc++.so (0x735e6a2000)
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $

[clang19 toolchain] 1|ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $ LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH $PWD/python --version
Python 3.15.0a1
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $



To create a python binary with a statically linked python library file use this command (after running make!):

/data/local/tmp/sysroot/usr/clang19/bin/clang \
 -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 \
 /data/local/tmp/develop/sysroot/usr/lib/libncursesw.a \
 -Xlinker \
 -export-dynamic \
 -o python \
 Programs/python.o \
 libpython3.15.a \
 -ldl \
 -llog \
 -lm


Check the resulst:

[clang19 toolchain] 1|ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $ ls -l python
-rwxrwxrwx 1 shell shell 37723552 2025-11-07 13:53 python
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $ file python
python: ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), for Android 31, built by NDK r27d (13750724), not stripped
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $ ldd $PWD/python
    linux-vdso.so.1 => [vdso] (0x7f3ebc7000)
    libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x7f35e57000)
    libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x7f38c77000)
    liblog.so => /system/lib64/liblog.so (0x7f38cd4000)
    libm.so => /apex/com.android.runtime/lib64/bionic/libm.so (0x7f38c83000)
    libc++.so => /system/lib64/libc++.so (0x7f32a4a000)
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $

[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $ ./python --version
Python 3.15.0a1
[clang19 toolchain] ASUS_I006D:/data/local/tmp/develop/Python-3.15.0a1 $


Trouble Shooting

If you get an error message like this:

CANNOT LINK EXECUTABLE "sed": cannot find "libselinux.so" from verneed[1] in DT_NEEDED list for "/system/bin/toybox"

add the library /system/lib64 to the LD_LIBRARY_PATH:

export LD_LIBRARY_PATH=/system/lib64:$LD_LIBRARY_PATH



History of this entry

08.11.2025

cleanup instructions

07.11.2025

initial release





How to compile OpenSSL in Android using the clang19 toolchain on the phone


How to compile OpenSSL in Android using the clang19 toolchain on the phone


To compile OpenSSL using the clang19 toolchain on the phone execute these commands in an adb session with initialized clang19 toolchain environment:


Init the clang19 toolchain if not already done:

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


Download the source files fro OpenSSL from here : https://openssl-library.org/source/

Copy the tar file to the phone, and unpack it in the directory /data/local/tmp/ (or a sub directory of this directory).


# correct the shebang in the Configure script
#
[ ! -r Configure.org ] && cp Configure Configure.org
sed -i -e "s#/usr/bin/env#/system/bin/env#g" Configure

# check the result
#
diff Configure Configure.org


# execute the OpenSSL configure script
#
./Configure --prefix=/system/usr
            --openssldir=/system/etc/tls \
            shared \
            no-hw \
            no-srp \
            enable-tls1_3

# start the build
#
make -j$( nproc )


To test OpenSSL after the build is done, execute these commands:

# correct the shebang in the wrapper script created by make
#
cp util/wrap.pl  util/wrap.pl.org
sed -i -e "s#/usr/bin/env#/system/bin/env#g" util/wrap.pl

# check the result
#
diff util/wrap.pl  util/wrap.pl.org

# run the tests
#
make test



 

History of this entry

18.04.2026

initial release





How to compile jsoncpp in Android using the clang19 toolchain on the phone (using cmake)



How to compile jsoncpp in Android using the clang19 toolchain on the phone (using cmake)


Source: https://github.com/open-source-parsers/jsoncpp/archive/refs/tags/1.9.7.tar.gz



Init the clang19 toolchain if not already done:

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


Download the source files:

wget https://github.com/open-source-parsers/jsoncpp/archive/refs/tags/1.9.7.tar.gz -O jsoncpp.tar.gz

Unpack the tar file

tar -xf jsoncpp.tar.gz

Create a directory for the build

mkdir build


Create the make files:

cd build

cmake .. -DCMAKE_BUILD_TYPE=Release


Build the library:

make




History of this entry

19.04.2026

initial release





How to compile curl in Android using the clang19 toolchain on the phone (using cmake and ninja)



How to compile curl in Android using the clang19 toolchain on the phone (using cmake and ninja)


Source: https://curl.se/download/curl-8.19.0.tar.bz2


Init the clang19 toolchain if not already done:

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


Download the source files:

wget https://curl.se/download/curl-8.19.0.tar.bz2 -o curl-8.19.0.tar.bz2

Unpack the tar file

tar -xf curl-8.19.0.tar.bz2


Create the directory for the build

cd curl-8.19.0

mkdir build


Create the config files for ninja using meson:

cmake -DCMAKE_INSTALL_PREFIX=/data/local/tmp/develop/sysroot_tmp/ -G Ninja ..


Build the binary and the libraries using ninja:

ninja




History of this entry

19.04.2026

initial release





How to compile bzip2 in Android using the clang19 toolchain on the phone (using meson and ninja)



How to compile bzip2 in Android using the clang19 toolchain on the phone (using meson and ninja)


Source: https://gitlab.com/bzip2/bzip2


Init the clang19 toolchain if not already done:

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


Download the source files:

wget https://gitlab.com/bzip2/bzip2/-/archive/master/bzip2-master.tar.gz?ref_type=heads -O bzip2.tar.gz

Unpack the tar file

tar -xf bzip2.tar.gz


Create the directory for the build

cd bzip2-master

mkdir build


Create the config files for ninja using meson:

meson -D buildtype=release   --prefix /data/local/tmp/develop/sysroot_tmp  build/


Build the binary and the libraries using ninja:

ninja -C build/


Note

If meson complains about a missing pytest Python module, install the module with this command:

pip3 install pytest




History of this entry

19.04.2026

initial release


 


Using the Android source code tree to compile binaries for Android



How to compile only a single binary file from Android


URL: https://xdaforums.com/t/guide-how-to-compile-only-a-single-binary-file-from-android.4764329/


How to compile only a single binary file from Android

While testing my guide on how to use gdb, I discovered that it is very easy to compile only a specific module with the build system used to compile the Android operating system. This feature allows you to compile only one specifc executable from Android, for example.

This guide, shows how this works.


Note:

Before using the commands in this guide you must once init the build environment, e.g. to init the build environment for the LineageOS:

# init the build environment - this must be done only once in each session
#
source build/envsetup

# "sake" is the code for the ASUS Zenfone 8 -- replace it with the code for your phone
#
lunch lineage_sake-bp1a-user


To list all known modules the command

allmod

can be used.

Be advised that there are many modules:

[xtrnaw7@t15g /devpool001/develop/LineageOS_22.2_original]$ allmod | wc -l
83474
[xtrnaw7@t15g /devpool001/develop/LineageOS_22.2_original]$


Most modules are used for the internal build process, and it does not make sense to build them separately, but there are also modules for the binary files in Android.

This build function can therefore be used to compile a binary file with different compiler options—for example, to compile an executable with debug code.

The name of a module may match the name of the binary file, but this is not necessary. Therefore, use grep to check whether there is a module for a binary file, examples:

[xtrnaw7@t15g /devpool001/develop/LineageOS_22.2_original]$ allmod | grep ethtool
ethtool.com.android.tethering
[xtrnaw7@t15g /devpool001/develop/LineageOS_22.2_original]$

[xtrnaw7@t15g /devpool001/develop/LineageOS_22.2_original]$ allmod | grep rsync
com.qti.feature2.anchorsync
rsync
[xtrnaw7@t15g /devpool001/develop/LineageOS_22.2_original]$


To compile for example an ethtool binary with debug infos do:

The source code for the ethtool binary are in the directory externals/ethtool.

To change the compiler options to compile ethtool change the file externals/ethtool/Android.bp.

Add the compiler flags

        "-O0",
        "-g3",
        "-fno-omit-frame-pointer",
        "-fno-inline",

and the new subsection

    strip: {
       none: true,
   },


to the section starting with

cc_binary {
    name: "ethtool",


This can be done either manually or by using this patch:

--- external/ethtool/Android.bp.org    2025-10-14 20:47:40.512672387 +0200
+++ external/ethtool/Android.bp    2025-10-14 20:49:52.703964884 +0200
@@ -60,6 +60,10 @@
         // causes a fair bit of binary bloat: "-DETHTOOL_ENABLE_PRETTY_DUMP",
         "-DPACKAGE=\"ethtool\"",
         "-DVERSION=\"6.5\"",
+        "-O0",
+        "-g3",
+        "-fno-omit-frame-pointer",
+        "-fno-inline",
     ],
     apex_available: [
         "com.android.tethering",
@@ -67,4 +71,7 @@
     ],
     installable: false,
     min_sdk_version: "30",
+    strip: {
+       none: true,
+   },
 }


The Android.bp file should then look like this

cat external/ethtool/Android.bp
[xtrnaw7@t15g /devpool001/develop/LineageOS_22.2_original]$ cat external/ethtool/Android.bp
package {
    default_applicable_licenses: ["external_ethtool_license"],
}

// Added automatically by a large-scale-change that took the approach of
// 'apply every license found to every target'. While this makes sure we respect
// every license restriction, it may not be entirely correct.
//
// e.g. GPL in an MIT project might only apply to the contrib/ directory.
//
// Please consider splitting the single license below into multiple licenses,
// taking care not to lose any license_kind information, and overriding the
// default license using the 'licenses: [...]' property on targets as needed.
//
// For unused files, consider creating a 'fileGroup' with "//visibility:private"
// to attach the license to, and including a comment whether the files may be
// used in the current project.
//
// large-scale-change included anything that looked like it might be a license
// text as a license_text. e.g. LICENSE, NOTICE, COPYING etc.
//
// Please consider removing redundant or irrelevant files from 'license_text:'.
// See: http://go/android-license-faq
license {
    name: "external_ethtool_license",
    visibility: [":__subpackages__"],
    license_kinds: [
        "SPDX-license-identifier-GPL",
        "SPDX-license-identifier-GPL-2.0",
        "SPDX-license-identifier-LGPL",
    ],
    license_text: [
        "COPYING",
        "LICENSE",
    ],
}

cc_binary {
    name: "ethtool",
    local_include_dirs: [
        "uapi",
        "libmnl",
        "libmnl/include",
    ],
    srcs: [
        "libmnl/src/*.c",
        "netlink/*.c",
        "[a-s]*.c",
        "t[a-d]*.c",
        // avoid test-*.c -- note these are shell globs, not regexps
        "t[f-z]*.c",
        "[u-z]*.c",
    ],
    cflags: [
        "-Wno-missing-field-initializers",
        "-Wno-gnu-pointer-arith",
        "-Wno-gnu-variable-sized-type-not-at-end",
        "-Wno-unused-parameter",
        "-DETHTOOL_ENABLE_NETLINK",
        // causes a fair bit of binary bloat: "-DETHTOOL_ENABLE_PRETTY_DUMP",
        "-DPACKAGE=\"ethtool\"",
        "-DVERSION=\"6.5\"",
        "-O0",
        "-g3",
        "-fno-omit-frame-pointer",
        "-fno-inline",
    ],
    apex_available: [
        "com.android.tethering",
        "//apex_available:platform",
    ],
    installable: false,
    min_sdk_version: "30",
    strip: {
       none: true,
   },
}
[xtrnaw7@t15g /devpool001/develop/LineageOS_22.2_original]$



Then compile ethtool using the command

m ethtool


Output of the command "m ethtool"
[xtrnaw7@t15g /devpool001/develop/LineageOS_22.2_original]$ m ethtool
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=15
LINEAGE_VERSION=22.2-20251014-UNOFFICIAL-sake
TARGET_PRODUCT=lineage_sake
TARGET_BUILD_VARIANT=user
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-2a-dotprod
TARGET_CPU_VARIANT=cortex-a76
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv8-a
TARGET_2ND_CPU_VARIANT=cortex-a76
HOST_OS=linux
HOST_OS_EXTRA=Linux-6.16.8-100.fc41.x86_64-x86_64-Fedora-Linux-41-(MATE-Compiz)
HOST_CROSS_OS=windows
BUILD_ID=BP1A.250505.005
OUT_DIR=out
PRODUCT_SOONG_NAMESPACES=vendor/asus/sake device/asus/sake kernel/asus/sm8350 hardware/google/interfaces hardware/google/pixel hardware/lineage/interfaces/power-libperfmgr hardware/qcom-caf/common/libqti-perfd-client vendor/qcom/opensource/usb/etc hardware
/qcom-caf/sm8350 hardware/qcom-caf/bootctrl vendor/qcom/opensource/commonsys/display vendor/qcom/opensource/commonsys-intf/display vendor/qcom/opensource/display vendor/qcom/opensource/data-ipa-cfg-mgr-legacy-um vendor/qcom/opensource/dataservices hardware
/qcom-caf/thermal-legacy-um hardware/qcom-caf/wlan
============================================
[100% 2/2] analyzing Android.bp files and generating ninja file at out/soong/build.lineage_sake.ninja
Warning: Module 'androidx.wear_wear' depends on non-existing optional_uses_libs 'wear-sdk'
Warning: Module 'androidx.wear.compose_compose-foundation' depends on non-existing optional_uses_libs 'wear-sdk'
Warning: Module 'webview' depends on non-existing optional_uses_libs 'com.android.extensions.xr'
out/soong/Android-lineage_sake.mk was modified, regenerating...
[100% 3/3] initializing legacy Make module parser ...
Adding CUSTOM_LOCALES [ast_ES gd_GB cy_GB fur_IT] to PRODUCT_LOCALES [en_US en_US af_ZA am_ET ar_EG ar_XB as_IN az_AZ be_BY bg_BG bn_BD bs_BA ca_ES cs_CZ da_DK de_DE el_GR en_AU en_CA en_GB en_IN en_XA es_ES es_US et_EE eu_ES fa_IR fi_FI fr_CA fr_FR gl_ES
gu_IN hi_IN hr_HR hu_HU hy_AM in_ID is_IS it_IT iw_IL ja_JP ka_GE kk_KZ km_KH kn_IN ko_KR ky_KG lo_LA lt_LT lv_LV mk_MK ml_IN mn_MN mr_IN ms_MY my_MM nb_NO ne_NP nl_NL or_IN pa_IN pl_PL pt_BR pt_PT ro_RO ru_RU si_LK sk_SK sl_SI sq_AL sr_Latn_RS sr_RS sv_SE
 sw_TZ ta_IN te_IN th_TH tl_PH tr_TR uk_UA ur_PK uz_UZ vi_VN zh_CN zh_HK zh_TW zu_ZA en_XC]
[100% 141/141 0s remaining] target Prebuilt: ethtool.com.android.tethering (out/target/product/sake/obj/EXECUTABLES/ethtool.com.android.tethering_intermediates/ethtool)

#### build completed successfully (05:08 (mm:ss)) ####

[xtrnaw7@t15g /devpool001/develop/LineageOS_22.2_original]$


---

The result should then look like this:

[xtrnaw7@t15g /devpool001/develop/LineageOS_22.2_original]$ file out/target/product/sake/obj/EXECUTABLES/ethtool.com.android.tethering_intermediates/ethtool
out/target/product/sake/obj/EXECUTABLES/ethtool.com.android.tethering_intermediates/ethtool: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, BuildID[md5/uuid]=304a63f64e76fbbf2641544f61de30a5, with debug_info, not stripped
[xtrnaw7@t15g /devpool001/develop/LineageOS_22.2_original]$


Notes

The stripped version of the created binary is in the directory  
To find the directory with the source code for a module this find command can be used (the command in this example searches the directory with the source code for the module "rsync"):

# execute in the top directory with the repositories
#
find . -type f -name Android.bp -exec grep -H "name: \"rsync\"" {} +



The source code for many binaries is located in sub directories in the directory ./external. To speed up the search, try the following first:

# execute in the top directory with the repositories
#
grep "name: \"rsync\"" external/*/Android.bp

In order to be able to debug an executable file on the phone with a debugger such as gdb, the source code should be available on the phone.


At least in LineageOS there are tools in the directory ./external that are not part of the LineageOS image like arping, iperf3, tracepath, traceroute6 that can be compiled using "m <toolname>".


Note that some modules (lz4, etc) are for compiling the necessary tools for Linux x86 on the PC to create the Android OS image .


Update 26.05.2026

Be aware, that depending on the general compiler options used in the config files in the repository, the binary created this way may not work on all CPU variants.

For the ASUS Zenfone 8 the general options are defined in the file ( "sake" is the code for the ASUS Zenfone 8)

device/asus/sake/BoardConfig.mk

example:

[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x]$ egrep "TARGET_ARCH|TARGET_CPU"  device/asus/sake/BoardConfig.mk
egrep: warning: egrep is obsolescent; using grep -E
TARGET_ARCH := arm64
TARGET_ARCH_VARIANT := armv8-a
TARGET_CPU_VARIANT := generic

#TARGET_ARCH := arm64
#TARGET_ARCH_VARIANT := armv8-2a-dotprod
#TARGET_CPU_VARIANT := cortex-a76

TARGET_CPU_ABI := arm64-v8a
[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x]$



The definitions that are not commented out are required to create a binary that runs on all arm64 CPUs (as far as I know); the commented-out definitions produce binaries that run only on specific arm64 CPUs.




History of this entry


26.05.2026

added the info about how to compile CPU type independent binaries

15.10.2025

initial release





How to build a program from Android (such as dmctl) as a statically linked binary


URL: https://xdaforums.com/t/guide-how-to-build-a-program-from-android-such-as-dmctl-as-a-statically-linked-binary.4789942/


How to build a program from Android (such as dmctl) as a dynamically linked binary or a statically linked binary

The dmctl binary is part of the Android OS. Therefore, it can be compiled using these instructions (see also How to compile only a single binary file from Android):

The commands in this guide apply to a repository containing a custom ROM based on Android 16, but should also work for other operating system versions.

Change to the root directory with the repository for the CustomROM and execute the commands

source build/envsetup

# sake is the code for the phone ASUS Zenfone 8 and bp2a is the buildID -- both values may vary depending on your device
#
lunch lineage_sake-bp2a-user

m dmctl


The result is then here:

[100% 197/197 2m37s remaining] Install: out/target/product/sake/system/bin/dmctl


The binaries in the directory ./system/bin are always stripped:

[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x_dev]$ ls -lh  out/target/product/sake/system/bin/dmctl
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 98K 26. Mai 15:34 out/target/product/sake/system/bin/dmctl
[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x_dev]$

[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x_dev]$ file  out/target/product/sake/system/bin/dmctl
out/target/product/sake/system/bin/dmctl: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, for Android 36, BuildID[md5/uuid]=0fca079010d3af4d24a0d9e466ce5a15, stripped
[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x_dev]$

the unstripped version of the created binary is in the directory ./symbols/system/bin, example:

[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x_dev]$ ls -lh  out/target/product/sake/symbols/system/bin/dmctl
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 507K 26. Mai 15:33 out/target/product/sake/symbols/system/bin/dmctl
[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x_dev]$

[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x_dev]$ file  out/target/product/sake/symbols/system/bin/dmctl
out/target/product/sake/symbols/system/bin/dmctl: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, for Android 36, BuildID[md5/uuid]=0fca079010d3af4d24a0d9e466ce5a15, with debug_info, not stripped
[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x_dev]$


In /e/ (and other CustomROMs based on LineageOS and also in TWRP and in the OrangeFox recovery) the Android.bp file for building dmctl is

system/core/fs_mgr/tools/Android.bp


To create a binary version with other options, edit that file.

To create a statically linked dmctl binary modify the section for dmctl in that file:

cc_binary {
    name: "dmctl",

    srcs: ["dmctl.cpp"],

    static_executable: true,

    static_libs: [
        "libfs_mgr",
        "libbase",
        "liblog",
    ],

    stl: "libc++_static",

    shared_libs: [],
}


To create a binary with debug information, add the section


    cflags: [
        "-O0",
        "-g",
    ],

to the definition for dmctl in that file.

Result:

[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x]$ file  out/target/product/sake/system/bin/dmctl
out/target/product/sake/system/bin/dmctl: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, for Android 36, BuildID[md5/uuid]=860a367cdb44c84291979e8bacdea148, stripped
[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x]$

[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x]$ file  out/target/product/sake/symbols/system/bin/dmctl
out/target/product/sake/symbols/system/bin/dmctl: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, for Android 36, BuildID[md5/uuid]=860a367cdb44c84291979e8bacdea148, with debug_info, not stripped
[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x]$

[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x]$ ls -lh out/target/product/sake/system/bin/dmctl out/target/product/sake/symbols/system/bin/dmctl

-rwxr-xr-x 1 xtrnaw7 xtrnaw7 3,3M 26. Mai 08:23 out/target/product/sake/symbols/system/bin/dmctl
-rwxr-xr-x 1 xtrnaw7 xtrnaw7 733K 26. Mai 08:23 out/target/product/sake/system/bin/dmctl
[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x]$



But be aware, that depending on the general compiler options used in the config files in the repository, this binary may not work on all CPU variants.

For the ASUS Zenfone 8 the general options are defined in the file ( "sake" is the code for the ASUS Zenfone 8)

device/asus/sake/BoardConfig.mk

example:

[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x]$ egrep "TARGET_ARCH|TARGET_CPU"  device/asus/sake/BoardConfig.mk
egrep: warning: egrep is obsolescent; using grep -E
TARGET_ARCH := arm64
TARGET_ARCH_VARIANT := armv8-a
TARGET_CPU_VARIANT := generic

#TARGET_ARCH := arm64
#TARGET_ARCH_VARIANT := armv8-2a-dotprod
#TARGET_CPU_VARIANT := cortex-a76

TARGET_CPU_ABI := arm64-v8a
[xtrnaw7@gem10 /datapool01/develop/e/a16_3.x]$



The definitions that are not commented out are required to create a binary that runs on all arm64 CPUs (as far as I know); the commented-out definitions produce binaries that run only on specific arm64 CPUs.


Notes

The usage for the dmctl binary from Android 16 is:

/data/local/tmp/dmctl -h
raspberry-dev:/ $ /data/local/tmp/dmctl -h
usage: dmctl <command> [command options]
       dmctl -f file
commands:
  create <dm-name> [-ro] <targets...>
  delete <dm-name>
  list <devices | targets> [-v]
  message <dm-name> <sector> <message>
  getpath <dm-name>
  getuuid <dm-name>
  ima <dm-name>
  info <dm-name>
  replace <dm-name> <targets...>
  status <dm-name>
  resume <dm-name>
  suspend <dm-name>
  table <dm-name>
  help

-f file reads command and all parameters from named file

Target syntax:
  <target_type> <start_sector> <num_sectors> [target_data]
234|raspberry-dev:/ $





A statically linked dmctl binary from Android 16 compiled for arm64 CPUs that also works on previous Android versions is available here for download:

dmctl_api36_android16_static

A unstripped version of that dmctl binary is available here for download:

dmctl_api36_android16_static_unstripped


Details:

raspberry-dev:/ $ file /data/local/tmp/dmctl_api36_android16_static*                                                                                                                                                   
/data/local/tmp/dmctl_api36_android16_static:            ELF executable, 64-bit LSB arm64, static, for Android 36, BuildID=860a367cdb44c84291979e8bacdea148, stripped
/data/local/tmp/dmctl_api36_android16_static_unstripped: ELF executable, 64-bit LSB arm64, static, for Android 36, BuildID=860a367cdb44c84291979e8bacdea148, not stripped
raspberry-dev:/ $

raspberry-dev:/ $ ls -lh /data/local/tmp/dmctl_api36_android16_static*
-rwxr-xr-x 1 shell shell 733K 2026-05-26 07:14 /data/local/tmp/dmctl_api36_android16_static
-rwxr-xr-x 1 shell shell 3.2M 2026-05-26 07:14 /data/local/tmp/dmctl_api36_android16_static_unstripped
raspberry-dev:/ $
 




dmctl binaries from different Android versions compiled for arm64 CPUs can be found here:

http://bnsmb.de/files/public/Android/binaries_for_arm64/dmctl/

Please note that these dmctl binaries are Android version dependent, e.g. the dmctl binary compiled for Android version X may or may not work in Android version Y.

As of 24.05.2026 there are dmctl binaries for Android 13, Android 14, Android 15, and Android 16.

----

History of this entry

26.05.2026

added the info about how to create statically linked binaries

20.01.2026

initial release


----
  
 

Links

 

 
 

Useful Android apps and tools


Show or Hide Table
URL
App
Comment
https://f-droid.org/ F-Droid
"F-Droid is an installable catalogue of FOSS (Free and Open Source Software) applications for the Android platform. The client makes it easy to browse, install, and keep track of updates on your device"




https://termux.dev/
Termux app

https://github.com/termux-user-repository/tur
Termux user repository
additional packages for Termux
https://packages.termux.dev/
Links to the Termux repositories

https://hax4us.github.io/2021-11-22-install-android-sdk-in-termux/ Instructions to install the SDK in the Android OS
https://github.com/lzhiyong/termux-ndk Android NDK version r29 (as of 20.04.2026) compiled for arm64 CPUs Note that the files for arm64 are in directories called x86_64 in this archive, example:

[xtrnaw7@t15g /data/develop/android/test/android-ndk-r29]$ file ./toolchains/llvm/prebuilt/linux-x86_64/bin/clang-21
./toolchains/llvm/prebuilt/linux-x86_64/bin/clang-21: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, stripped
[xtrnaw7@t15g /data/develop/android/test/android-ndk-r29]$



https://play.google.com/store/apps/details?id=moe.shizuku.privileged.api
Shizuku

App that can be used to become the user shell in a local shell on the phone

see How to become the user shell in a local terminal on the phone  

https://github.com/bk138/droidVNC-NG?tab=readme-ov-file
droidVNC
VNC server for Android that does NOT require root access

see Remote Access to an Android phone     

https://github.com/AmanoTeam/android-gcc-cross/
GitHub repository with a GCC toolchain for Android and GCC cross-compiler for Android on Linux, Windows, and MacOS
see How to compile a C or C++ program for Android in Android with gcc without root access
and
How to compile a C program for Android using a recent GCC cross-compiler
 

 

back top top