Sign in Join
Wiki copytemporary

Android: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11All Articles about Android are listed in [[Portal:Android]].
22
33*(Android only)*
44
55## Android target
66
77Support for the Android target is present starting from FPC 3.0.
88
99Supported CPUs:
1010
1111- ARM (`CPU_TARGET=arm`)
1212- x86 (`CPU_TARGET=i386`)
1313- MIPS (`CPU_TARGET=mipsel`)
1414- ARM64 (`CPU_TARGET=aaarch64`) - in FPC 3.2+
1515- x86-64 (`CPU_TARGET=x86_64`) - in FPC 3.2+
1616- [[FPC JVM|JVM]] (not discussed on this page)
1717
1818## Android NDK
1919
2020You need to download and install Android NDK in order to get the cross binutils that compile programs for the android target on your current machine.
2121
2222Download Android NDK using this link: <https://developer.android.com/ndk/downloads/index.html>
2323
2424Extract it to some folder.
2525
2626## Download FPC for Android
2727
2828### Release version
2929
3030If you develop for Android using a Windows machine you can download a setup package which contains cross-compilers for Android (ARM, i386, MIPS). After installation of the cross-compilers you can build binaries for Android without any additional steps.
3131
3232For other host platforms you need to download the FPC sources archive and build a cross-compiler as described below.
3333
3434Download the latest release cross-compilers and FPC sources here: <http://freepascal.org/download.html>
3535
3636### Development version
3737
3838The development (trunk) version of FPC may contain new features or bug fixes compared to the latest release version.
3939
4040Check out the latest trunk sources of FPC using the following command:
4141
4242`git clone https://gitlab.com/freepascal.org/fpc/source.git fpcsrc`
4343
4444Now you have the latest compiler sources in the `fpcsrc` sub-folder.
4545
4646## Building cross compiler
4747
4848You need to have a working installation of the latest version of FPC for your host platform in order to create the cross-compiler.
4949
5050This tutorial describes how to build a cross-compiler for the **`arm-android`** target on Windows. But the tutorial can be applied to any system with small obvious modifications.
5151
5252Use the similar approach to build a **`aarch64-android`** or **`i386-android`** or **`x86_64-android`** or **`mipsel-android`** cross-compiler.
5353
5454Let's assume the following paths:
5555
5656- Android NDK path: `C:\Program Files\Android SDK\android-ndk-r12b`
5757- FPC svn sources path: `C:\Develop\FPC\fpcsrc`
5858- The cross-compiler installation path: `C:\Develop\FPC\pp`
5959
6060Add the path to Android binutils to the PATH environment variable. In this tutorial the path is: `C:\Program Files\Android SDK\android-ndk-r12b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows\bin`
6161
6262Open the Command line prompt and `cd` to the root of FPC sources folder: `C:\Develop\FPC\fpcsrc`
6363
6464Execute the following command:
6565
6666`make clean crossall crossinstall OS_TARGET=android CPU_TARGET=arm INSTALL_PREFIX=C:\Develop\FPC\pp`
6767
6868After that you should have the cross-compiler and units installed in folder `C:\Develop\FPC\pp` By default all units are built with -O2 optimization switch. Also software FPU emulation is used for ARM CPU by default. If you need to specify different compiler options for building, use the `CROSSOPT` parameter. For example if you wish to build units with hardware FPU support and ARMv7a CPU use the following command:
6969
7070`make clean crossall crossinstall OS_TARGET=android CPU_TARGET=arm CROSSOPT="-Cparmv7a -Cfvfpv3" INSTALL_PREFIX=C:\Develop\FPC\pp`
7171
7272Now create a new `fpc.cfg` file in folder `C:\Develop\FPC\pp\bin\i386-win32` and paste into it the following text:
7373
7474 -FuC:\Develop\FPC\pp\units\$FPCTARGET*
7575
7676 #ifdef android
7777 #ifdef cpuarm
7878 -FlC:\Program Files\Android SDK\android-ndk-r12b\platforms\android-21\arch-arm\usr\lib
7979 #endif
8080 #ifdef cpuaarch64
8181 -FlC:\Program Files\Android SDK\android-ndk-r12b\platforms\android-21\arch-arm64\usr\lib
8282 #endif
8383 #ifdef cpui386
8484 -FlC:\Program Files\Android SDK\android-ndk-r12b\platforms\android-21\arch-x86\usr\lib
8585 #endif
8686 #ifdef cpux86_64
8787 -FlC:\Program Files\Android SDK\android-ndk-r12b\platforms\android-21\arch-x86_64\usr\lib
8888 #endif
8989 #ifdef cpumips32
9090 -FlC:\Program Files\Android SDK\android-ndk-r12b\platforms\android-21\arch-mips\usr\lib
9191 #endif
9292 #endif
9393
9494## Compiling programs
9595
9696Now, when the cross-compiler is ready, you can compile programs for the Android target:
9797
9898`C:\Develop\FPC\pp\bin\i386-win32\ppcrossarm -Tandroid testprog.pas`
9999
100100## Notes
101101
102102- The compiler does NOT define **`LINUX`** during compilation! It defines **`UNIX`** and **`ANDROID`** though.\
103103 (Background: Android is not completely Linux compatible, e.g. a few syscalls and default library functions e.g. in pthreads, ... are missing, and it generally behaves different in a few ways. This makes the amount of defines manageable by avoiding `if defined(linux) and not defined(android)`. Actually, the list of things that are different is only growing).
104104
105105- Shared libraries do not have **`argc/argv`** available (i.e. set to 0 or nil) because of Android.
106106
107107- The **System** unit contains some useful [Android-specific functions](https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/rtl/android/sysandroidh.inc?view=markup).
108108
109109- The compiler and RTL do special processing for JNI shared libraries. The compiler treats a library as a JNI library only if the library exports the **`JNI_OnLoad`** function. Therefore, if you are creating a JNI shared library, always export `JNI_OnLoad`, even if it is empty.
110110
111111- For JNI shared libraries standard output and error output are redirected to the Android system log. Therefore you can use `writeln()` to write to the system log.
112112
113113- By default FPC builds PIC enabled shared libraries and executables for the Android target. PIC shared libraries work on any Android version (tested even on Android 1.5). But PIC executables can run only on Android 4.1+. To run executables on older versions of Android you need to disable PIC by passing the **`-Cg-`** switch to the compiler.
114114
115115## Known issues
116116
117-- Shared libraries compiled with FPC 3.0 does not work on Android 6.0+ and executables does not run on Android 5.0+. Starting from Android 6.0 (Marshmallow), it is required to build PIC compatible shared libraries. Starting from Android 5.0 (Lollipop), it is required to build PIC compatible executables (PIE).<span style="color:green">**\
118- PIC support for the Android target is present starting from FPC 3.0.2.**</span>\
117+- Shared libraries compiled with FPC 3.0 does not work on Android 6.0+ and executables does not run on Android 5.0+. Starting from Android 6.0 (Marshmallow), it is required to build PIC compatible shared libraries. Starting from Android 5.0 (Lollipop), it is required to build PIC compatible executables (PIE).**\
118+ PIC support for the Android target is present starting from FPC 3.0.2.**\
119119 NOTE: By default FPC 3.0.2+ builds PIC enabled shared libraries and executables for the Android target. PIC shared libraries work on any Android version (tested even on Android 1.5). But PIC executables can run only on Android 4.1+. To run executables on older versions of Android you need to disable PIC by passing the `-Cg-` switch to the compiler.
120120- Shared libraries compiled with FPC 3.0.x does not work on Android 8.0+ when an application targets API 26+. This is caused by usage of syscalls which are blocked by SECCOMP starting from Android 8.\
121- <span style="color:green">**This issue is fixed in FPC 3.2.**</span>
121+ **This issue is fixed in FPC 3.2.**
122122- If you use the **cwstring** unit in a JNI shared library, your Java application will hang when loading the library on Android 4.0 or earlier. This also applies to any unit which dynamically loads shared libraries during initialization. See more information below.\
123- <span style="color:green">**This issue is fixed in FPC 3.2.**</span>
123+ **This issue is fixed in FPC 3.2.**
124124- The **clocale** unit is not implemented in FPC 3.0.\
125- <span style="color:green">**It is implemented in FPC 3.2.**</span>
125+ **It is implemented in FPC 3.2.**
126126- The **netdb** unit is unusable in FPC 3.0 due to missing configuration of DNS servers.\
127- <span style="color:green">**This issue is fixed in FPC 3.2.**</span>
127+ **This issue is fixed in FPC 3.2.**
128128- The `Now` function always returns a GMT time in FPC 3.0.\
129- <span style="color:green">**This issue is fixed in FPC 3.2.**</span>
129+ **This issue is fixed in FPC 3.2.**
130130- The following functions return unusable paths in FPC 3.0: `GetTempDir, GetAppConfigDir, GetAppConfigFile, GetUserDir`.\
131- <span style="color:green">**This issue is fixed in FPC 3.2.**</span>
131+ **This issue is fixed in FPC 3.2.**
132132
133133## Freeze during shared library initialization on Android prior 4.1
134134
135135If your shared library contains a unit which performs dynamic loading of other shared libraries using `LoadLibaray()` or `dlopen()`, your library may fail to load on Android 4.0 or earlier. The library loading will freeze in such case. One of the units, which can trigger the issue is **cwstring**.
136136
137137Due to a bug in Android versions prior to 4.1, the `dlopen()` API function does not support recursive calls. When a shared library is being loaded by JVM, using `dlopen()`, the library initialization is executed, including initialization code of all units in the library. If a unit initialization code calls `dlopen()` - it simply hangs, since the initial `dlopen()` is not finished yet and recursion is not allowed.
138138
139-<span style="color:green">**This issue is fixed in FPC 3.2.0**</span>: To workaround this issue the compiler uses the following trick: If a library exports `JNI_OnLoad()`, then no unit initialization is performed during library load. The initialization is called when JVM has loaded the library and then calls `JNI_OnLoad()`.
139+**This issue is fixed in FPC 3.2.0**: To workaround this issue the compiler uses the following trick: If a library exports `JNI_OnLoad()`, then no unit initialization is performed during library load. The initialization is called when JVM has loaded the library and then calls `JNI_OnLoad()`.
140140
141141Therefore, if you are creating a JNI shared library, always export `JNI_OnLoad`, even if it is empty.
142142
143143Also you can trigger this bug if you have a JNI shared library, which use other shared library, created using FPC. The loading of this second library may hang. To workaround this, you need to export an empty `JNI_OnLoad()` function in the second library. Then you need to call `JNI_OnLoad()` from the initialization of the first library.
144144
145145## See also
146146
147147- [[Android tutorial]]
148148- You can use the [[pas2jni]] utility to easily create JNI shared libraries from your existing code and use it in Android native Java applications.
149149- [[Cross compiling]] for cross compiling from Linux, macOS and Windows along with other useful cross-compilation information.
150150
151151## External links
152152
153153- [Tutorial "Lazarus and Android"](http://sourceforge.net/projects/laztoapk/files/Lazarus%20and%20Android.pdf/download) (PDF file)
154154- [How to create Android apps with Lazarus](https://pascaldelphilazarus.wordpress.com/2014/06/02/how-to-create-android-apps-with-lazarus/)
155155- [How to setup cross-compilation to Android](https://forum.lazarus.freepascal.org/index.php/topic,32553.0.html) (Lazarus Forum)
156156
157157---
158158*From the Free Pascal wiki, page "Android", as it stood on 2021-11-22 after a change by BeniBela, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history