Cross-compile GLib for Android
17 Jul 2016Prepare cross-compile environment
Install Android NDK and standalone toolchain
Update: You may now use Android NDK r15c and beyond. I have made an all-in-one script repo at my GitHub repo
First, you need to have Android NDK r10e installed, which can be downloaded from:
- Darwin: https://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip
- Linux: https://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip
- Windows: https://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip
- Linux 32-bit (x86): http://dl.google.com/android/ndk/android-ndk-r10e-linux-x86.bin
- Linux 64-bit (x86_64): http://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin
Pay attention to the NDK version we are using: r10e
. This is the version that can successfully compile the GLib library for Android. As the time of writing, the newest NDK version is r12b
. Yet using of this version is NOT RECOMMENDED, because some changes the GCC toolchain makes the compiling process fail (I will explain later).
Then, make a standalone toolchain using the script at ${NDK}/build/tools/make-standalone-toolchain.sh
. For more details, refer to my previous blog on Three Ways to Use Android NDK Cross Compiler or Android NDK doc.
We have made a standalone NDK toolchain targeting Android arm
architecture, API level 19, using gnustl
C++ library, and GCC version 4.9
, host system type is linux-86_64
.
Install necessary packages in Ubuntu
Several packages needs to be installed because GLib
and its dependencies use GNU Autotools.
Then we need to specify Android version binutils for cross compiling and set proper compiler flags. I have a script to do the environment configuration.
Save it, e.g. glib-env-prep.sh
, and source it to make changes effective in current shell immediately:
Compile and install dependency libraries
The most haunting experience in compiling sources yourself is probably handling dependencies.
We are out of no exception this time.
To make it worse, we are cross-compiling GLib for Android, and that means we need to cross-compile not only GLib itself, but also three other dependencies: libiconv
, libffi
and gettext
.
You may also cross-compile PCRE
but that’s not a mandatory dependency.
Compile libiconv 1.14
Then static library libiconv.a
will be installed to /opt/android/lib
.
Notice here that for host
arch we used arm-eabi
instead of arm-linux-androideabi
, because arm-eabi
is meant for building Android kernel. In general these two are slightly different. Though arm-linux-androideabi
may work, I have not verified it so I cannot give any gurantees. Also, no need to run autogen.sh
as it may confuse the build system and host system architectures.
Compile libffi 3.2.1
libffi is the Portable Foreign Function Interface Library and is a prerequisite for building GLib. It is an interface that allows code written in one language to call code written in another language.
The two lines beginning with sed
is to make package install headers into the conventional ${PREFIX}/include
instead of ${PREFIX}/lib/libffi-3.2.1/include
.
Thanks these instructions from LFS [1], otherwise we will be adding the -I
and -L
flags for libffi
in our cross compile environment setting script.
Compile gettext 0.18.3
First get the source code for gettext 0.18.3
To compile gettext-0.18.3
, a patch must be applied.
In gettext-tools/src/msginit.c
, change line 1088 from
to
I have made a patch for it:
Save it as gettext-0.18.3-android.patch
and apply it:
Then configure and compile it.
We disabled some non-necessary functions. Again, no need to run autogen.sh
.
Compile GLib
Finally, let’s compile the latest glib-2.48.1
.
Cross-compiling GLib requires a “cache file”, which tells GLib how to set some of the variables manually. For more details see GLib’s official doc at https://developer.gnome.org/glib/stable/glib-cross-compiling.html.
The cache file we will be using is called android.cache
:
We will also make it read-only to prevent it from being overwritten by the automatic configure
:
Should you see any errors from executing autogen.sh
, fix them.
For example, it could tell you that no package ‘zlib’ or ‘libffi’ found, and that’s why we have installed it at the very beginning.
If you don’t want waste your time compiling an additional PCRE
library like I do, then the last argument --with-pcre=no
will be your life saver.
So, finally, we are done!! The ${PREFIX}/lib
folder (/opt/android/lib
in our case) will contain libglib-2.0.so
, libgio-2.0.so
, libgmodule-2.0.so
, libgthread-2.0.so
and other built libraries/binaries.
References
- [1] http://www.linuxfromscratch.org/blfs/view/svn/general/libffi.html
- [2] https://groups.google.com/forum/#!topic/lcm-users/Ly-xvHphpcY
- [3] http://mathslinux.org/?p=268
- [4] https://www.gnu.org/software/libiconv/
- [5] http://www.linuxfromscratch.org/lfs/view/development/chapter06/gettext.html
- [6] https://mssun.me/blog/build-android-toolchain.html
- [7] https://gist.github.com/mssun/19070cc35d7a38c9ea21
- [8] https://android.googlesource.com/platform/prebuilts/android-emulator-build/qemu-android-deps/+archive/master.tar.gz
- [9] http://forum.xda-developers.com/showthread.php?t=2723240
- [10] https://dl.dropboxusercontent.com/u/23869279/Files/cc.sh
- [11] https://mail.gnome.org/archives/gtk-devel-list/2011-March/msg00096.html
- [12] https://gist.github.com/nddrylliog/4688209
Appendix
-
I have tried NDK
r12b
with both API level 23 and 19. But both of them cannot compile. When compiling thegettext
, API 23 will give error on “cannot find <stdio_ext.h>“ and API 19 will give error on “cannot find <search.h>“. -
If you encountered an error complaining
gets
not defined when compilinglibiconv
, the following solutions may help you:- https://github.com/mxe/mxe/commit/8e4ab07b8e8ff9642148e411d58acebf43ae0a3b
- https://gist.github.com/paulczar/5493708
-
If you want to use
with-pcre=system
when configuring GLib, you need to cross-compile PCRE 8.39 and install it:./configure --build=${BUILD_SYS} --host=arm-eabi --disable-rpath --prefix=${PREFIX} --enable-unicode-properties
And good luck on fixing any error that may pop up.