说明

交叉编译Android平台glib库,参考的是https://segmentfault.com/a/11...,讲述的非常详尽。基本上一步步顺着做,就能完成编译。但是在个别步骤上还是遇到其他问题,于是记录成文,供参考。

编译环境
Linux ubuntu 3.19.0-25-generic #26~14.04.1-Ubuntu

步骤

操作跟https://segmentfault.com/a/11...完全相同的地方,仅提及步骤,并标注参考,不再赘述。

1.下载并安装Android NDK

下载地址:https://developer.android.com...
找到对应的平台版本,下载后直接解压即可。
我下载的是:android-ndk-r13b-linux-x86_64.zip

2.安装必要工具

参考

3.设置NDK和SYSROOT环境变量

参考
这里注意,我的目标平台是Android5.1版本,SYSROOT的环境变量为:
export SYSROOT="$NDK/platforms/android-22/arch-arm"

4.编译依赖库

4.1 libiconv

版本:1.14
下载地址:http://ftp.gnu.org/pub/gnu/li...
编译参考资料:编译可在Android上运行的libiconv库

4.2 gettext

版本:0.19.8.1
下载地址:http://ftp.gnu.org/pub/gnu/ge...
编译参考资料:编译可在Android上运行的gettext库
注意:configure时,不需要LDFLAGS参数,我按参考资料,反而configure会报找不到“./gettext-tools/gnulib-lib/.lbs/”目录,configure命令可以参考如下:

CPP="arm-linux-eabi-gcc -E" CPPFLAGS="-I${SYSROOT}/usr/include" ./configure --prefix="${SYSROOT}/usr" --host=arm-linux-eabi CFLAGS="--sysroot $SYSROOT"

4.3 pcre

版本: 8.40
下载地址:https://sourceforge.net/proje...
编译参考资料:编译可在Android上运行的pcre库

4.4 libffi

版本:3.2.1
下载地址: ftp://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz
编译参考资料:编译可在Android上运行的libffi库

5.下载glib源码

开发版本下载地址:https://github.com/GNOME/glib...
稳定版本下载地址:https://ftp.gnome.org/pub/gno...
注意,稳定版本源码中直接包含了configure脚本,而开发版本源码中没有该脚本,需要使用autogen.sh生成。

6.编写android.cache

参考

7.运行autogen.sh(稳定版本不需此步骤)

参考

8.运行configure

参考
直接参考以上博文进行Makefile生成,会有如下几个错误,这里特别说明下。

8.1 找不到libmount

暂时没有追究libmount库的用途,报这个错误的原因,应该是由于我的交叉编译环境中缺少libmount库导致的。暂时采取规避该错误的方法,在configure中显式声明不需要libmount库即可,如下:

CPP="arm-linux-androideabi-gcc -E" CPPFLAGS="-I${SYSROOT}/usr/include" CFLAGS="-fPIC " CXXFLAGS="-fPIC" LDFLAGS="-fPIC" ./configure --prefix="${SYSROOT}/usr" --host=arm-linux-androideabi --cache-file=android.cache CFLAGS="--sysroot $SYSROOT" --enable-shared --enable-gtk-doc-html=no --enable-man=no --enable-always-build-tests=no --enable-installed-tests=no --enable-libmount=no

8.2 Makefile依赖库未使用交叉环境的版本

采用上面的configure命令,生成的Makefile中有如下信息
……
ICONV_LIBS =
……
XGETTEXT = /usr/bin/xgettext
……
PCRE_CFLAGS = -I/usr/local/include
PCRE_LIBS = -L/usr/local/lib -lpcre
……
LIBFFI_CFLAGS =
LIBFFI_LIBS = -lffi
……
发现并未使用${SYSROOT}指定的版本,例如pcre直接使用了编译宿主机上的pcre版本,make时会报不兼容错误:

这里采用了一种比较笨的办法,分别制定这些变量的路径,如下:

CPP="arm-linux-androideabi-gcc -E" CPPFLAGS="-I${SYSROOT}/usr/include" CFLAGS="-fPIC " CXXFLAGS="-fPIC" LDFLAGS="-fPIC" XGETTEXT="${SYSROOT}/usr/bin/xgettext"  PCRE_CFLAGS="-I${SYSROOT}/usr/include" PCRE_LIBS="-L${SYSROOT}/usr/lib -lpcre" LIBFFI_CFLAGS="-I${SYSROOT}/usr/lib/libffi-3.2.1" LIBFFI_LIBS="-L${SYSROOT}/usr/lib -lffi" ICONV_LIBS="-L${SYSROOT}/usr/lib -liconv" ./configure --prefix="${SYSROOT}/usr" --host=arm-linux-androideabi --cache-file=android.cache CFLAGS="--sysroot $SYSROOT" --enable-shared --enable-gtk-doc-html=no --enable-man=no --enable-always-build-tests=no --enable-installed-tests=no --enable-libmount=no

应该是有一种办法,统一指定到${SYSROOT}下的,没理解--prefix="${SYSROOT}/usr"的含义,感觉这个参数应该是做这个用的,但是没有生效。

9.编译和安装

make
make install
即完成在交叉编译环境上的编译和安装,在${SYSROOT}/usr/lib目录中可以看到libglib-2.0.so。

10.功能验证

直接使用glib库下的gio/tests/gdbus-example-peer.c,模拟进程间的点对点通讯。

10.1 编译

arm-linux-eabi-gcc --sysroot=$SYSROOT -fPIE -pie gdbus-example-peer.c -o gdbus-example-peer -I${SYSROOT}/usr/include/ -I${SYSROOT}/usr/include/glib-2.0 -I${SYSROOT}/usr/lib/glib-2.0/include/ -lglib-2.0 -lgio-2.0 -lgobject-2.0

10.2 推送依赖库

将$SYSROOT/usr/lib下的如下库,推送到设备的/system/lib目录下
libffi.so
libffi.so.6
libgio-2.0.so
libglib-2.0.so
libgmodule-2.0.so
libgobject-2.0.so
libpcre.so

10.3 运行验证

将编译好的gdbus-example-peer推送到设备/data目录下,并赋予可执行权限。分别在两个shell中运行如下命令:

adb shell /data/gdbus-example-peer --server --address unix:abstract=myaddr
adb shell /data/gdbus-example-peer --address unix:abstract=myaddr

运行结果如下图,可以看到左侧的服务器进程成功的跟右侧的客户端进程完成通讯交互。

10.4 关于运行结果中的告警信息

WARNING: linker: /data/gdbus-example-peer: unused DT entry: type 0x6ffffffe arg 0x8c0
WARNING: linker: /data/gdbus-example-peer: unused DT entry: type 0x6fffffff arg 0x1
WARNING: linker: Unsupported flags DT_FLAGS_1=0x9
关于该问题,请参考http://stackoverflow.com/ques...

载入中...
tntzlx tntzlx

2 声望

发布于专栏

大饼

开源代码分析&工作中遇到的问题

1 人关注