-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Common porting problems
-
Most programs expect that target is FHS compliant. They have hardcoded paths like
/etc
,/bin
,/usr/share
,/tmp
which are not available in Termux at standard locations but only in$TERMUX_PREFIX
. -
tmpnam()
function may not respectTMPDIR
variable and use hardcoded path to/tmp
directory on some Android builds. This was changed by commit 439ebbd3 in Bionic libc but some new devices still use the oldtmpnam()
implementation. -
The Android bionic libc does not have iconv and gettext/libintl functionality built in. A
libandroid-support
package contains these and may be used by all packages. -
"error: z: no archive symbol table (run ranlib)" usually means that the build machine's libz is used instead of the one for cross-compilation due to the builder library -L path being setup incorrectly.
-
rindex(3) does not exist, but strrchr(3) is preferred anyway.
-
<sys/termios.h> does not exist, but <termios.h> is the standard location.
-
<sys/fcntl.h> does not exist, but <fcntl.h> is the standard location.
-
<sys/timeb.h> does not exist (removed in POSIX 2008), but ftime(3) can be replaced with gettimeofday(2).
-
<glob.h> does not exist, but is available through the
libandroid-glob
package. -
SYSV shared memory is not supported by the kernel. A
libandroid-shmem
package, which emulates SYSV shared memory on top of the ashmem shared memory system, is available. Use it withLDFLAGS+=" -landroid-shmem
. -
SYSV semaphores are not supported by the kernel. The package
libandroid-posix-semaphore
supports named semaphores and functions such assem_open
,sem_close
andsem_unlink
. -
Starting from Android 8, a Seccomp was enabled for applications. Seccomp forbids usage of some system calls which results in crash with
Bad system call
errors. -
Starting from Android 8, programs cannot use
tcsetattr()
withTCSAFLUSH
parameter due to SELinux. UseTCSANOW
instead. -
Starting from Android 9, Seccomp began to block
setuid()
-related system calls. Since Termux is primarily for single-user non-root usage, setuid/setgid functionality is discouraged anyway.
<dlfcn.h> declares
RTLD_NOW=0; RTLD_LAZY=1; RTLD_LOCAL=0; RTLD_GLOBAL=2; RTLD_NOLOAD=4; // 32-bit
RTLD_NOW=2; RTLD_LAZY=1; RTLD_LOCAL=0; RTLD_GLOBAL=0x00100; RTLD_NOLOAD=4; // 64-bit
These differs from glibc ones in that
-
They differ in value from glibc ones, so cannot be hardcoded in files (DLFCN.py in python does this)
-
They are missing some values (
RTLD_BINDING_MASK
, ...)
The Android dynamic linker is located at /system/bin/linker
(32-bit) or
/system/bin/linker64
(64-bit). Here are source links to different versions of
the linker:
Some notes about the linker:
-
The linker warns about unused dynamic section entries with a
WARNING: linker: $BINARY: unused DT entry: type ${VALUE_OF_d_tag}
message. -
The supported types of dynamic section entries have increased over time.
-
The Termux build system uses termux-elf-cleaner to strip away unused ELF entries causing the above mentioned linker warnings.
-
DT_RPATH
, the list of directories where the linker should look for shared libraries is not supported, so is stripped away.DT_RUNPATH
should be used instead (supported since Android 7.0). -
Symbol visibility when opening shared libraries using
dlopen()
works differently. On a normal linker, when an executable linking against a shared library libA dlopen():s another shared library libB, the symbols of libA are exposed to libB without libB needing to link against libA explicitly. This does not work with the Android linker, which can break plug-in systems where the main executable dlopen():s a plug-in which does not explicitly link against some shared libraries already linked to by the executable. See the relevant NDK issue for more information.