1、概述
glib的ndk编译是一个复杂麻烦的过程。 这里使用的是 glib-V2.5.83版本,因为当时 arm32位编译用的就是v2.5.83。 ndk 是用的是当下次新版本:android-ndk-r21e 。 环境:
- glib版本2.58.3
- ndk版本android-ndk-r21e, 选的平台版本target, platform也是21
- 编译环境Ubuntu 16.04.2 LTS
- libffi: v3.3
- libiconv:v1.16
- gettext:v0.21
编译重度参考了这个:http://mobileinsight.net/cross-compile-glib-for-android.html 只是它是比较老的编32位的方法。文中会出现比较多引用这个文章的内容
2、glib的编译依赖
glib 不是一个独立库字节跑脚本就能编译下来的。
2.1、需要用到的工具:
$ sudo apt-get update && sudo apt-get upgrade
$ sudo apt-get install build-essential
$ sudo apt-get install pkg-config automake autoconf libtool
$ sudo apt-get install zlib1g-dev libffi-dev libtool-bin
2.2、需要前置的编译库:
- libiconv:v1.16
- libffi: v3.3
- gettext:v0.21
因为没有使用pcre和libmount所以这2个不编译
2.3、前置准备
需要下载android-ndk-r21e 并且制作独立编译工具链,参考官方做法:https://developer.android.com/ndk/guides/standalone_toolchain.html 独立工具链制作为64位版本,
$NDK/build/tools/make_standalone_toolchain.py \
--arch arm64 --api 21 --install-dir /home/share/my-android-toolchain64
3、编译libiconv:v1.16
下载对应版本:https://ftp.gnu.org/pub/gnu/libiconv/ 设置环境变量:
export PATH=/home/share/ide/my-android-toolchain64/bin:$PATH
export ANDROID_HOST=aarch64-linux-android
export ANDROID_BUILD=linux-x86_64
export ANDROID_ARCH=arm64
export ANDROID_NDK=/home/share/ide/android-ndk-r21e
export ANDROID_VERSION=21
export ANDROID_TOOLCHAIN_VERSION=4.9
export ANDROID_SYSROOT=/home/share/ide/my-android-toolchain64/sysroot
export CFLAGS=--sysroot=$ANDROID_SYSROOT
export CPPFLAGS=--sysroot=$ANDROID_SYSROOT
export AR=$ANDROID_HOST-ar
export RANLIB=$ANDROID_HOST-ranlib
export PREFIX=/home/share/work/prefix
export NDK_TOOLCHAIN=/home/share/ide/my-android-toolchain64
export SYSROOT=/home/share/ide/my-android-toolchain64/sysroot
export LDFLAGS="-Wl,-rpath-link=-I${SYSROOT}/usr/lib -L${SYSROOT}/usr/lib -L${NDK_TOOLCHAIN}/lib"
export LIBS="-lc"
执行配置:
./configure --host=$ANDROID_HOST --with-sysroot=$ANDROID_SYSROOT --prefix=${PREFIX} --disable-rpath --enable-static --enable-shared
成功后make,然后make install 会把对应的 .a .so和h文件安装到–prefix目录下 注意点:如果发现执行配置出错可能是环境变量设置错了 进行修改。配置不懂的地方:./configure -h 。其中LDFLAGS LIBS CFLAGS 这几个是直接使用的环境变量的不需要传递给 configure help里有说明。
4、编译libffi: v3.3
这里有个要修改的地方
$ cd libffi-3.3
$ sed -e '/^includesdir/ s/$(libdir).*$/$(includedir)/' -i include/Makefile.in
$ sed -e '/^includedir/ s/=.*$/=@includedir@/' -e 's/^Cflags: -I${includedir}/Cflags:/' -i libffi.pc.in
设置变量,配置编译步骤和***编译libiconv:v1.16***一样
export PATH=/home/share/ide/my-android-toolchain64/bin:$PATH
export ANDROID_HOST=aarch64-linux-android
export ANDROID_BUILD=linux-x86_64
export ANDROID_ARCH=arm64
export ANDROID_NDK=/home/share/ide/android-ndk-r21e
export ANDROID_VERSION=21
export ANDROID_TOOLCHAIN_VERSION=4.9
export ANDROID_SYSROOT=/home/share/ide/my-android-toolchain64/sysroot
export CFLAGS=--sysroot=$ANDROID_SYSROOT
export CPPFLAGS=--sysroot=$ANDROID_SYSROOT
export AR=$ANDROID_HOST-ar
export RANLIB=$ANDROID_HOST-ranlib
export PREFIX=/home/share/work/prefix
export NDK_TOOLCHAIN=/home/share/ide/my-android-toolchain64
export SYSROOT=/home/share/ide/my-android-toolchain64/sysroot
export LDFLAGS="-Wl,-rpath-link=-I${SYSROOT}/usr/lib -L${SYSROOT}/usr/lib -L${NDK_TOOLCHAIN}/lib"
export LIBS="-lc"
export BUILD_SYS=x86_64-linux-gnu
export CROSS_PREFIX=/home/share/ide/my-android-toolchain64/bin/aarch64-linux-android
export CC=${CROSS_PREFIX}-gcc
export SYSROOT=/home/share/ide/my-android-toolchain64/sysroot
export CFLAGS="--sysroot=${SYSROOT} -I${SYSROOT}/usr/include -I${PREFIX}/include -fPIE -DANDROID -Wno-multichar"
./configure --prefix=${PREFIX} --host=aarch64-linux-android --disable-multi-os-directory
注意:
如果出现下载的版本没有./configure 要先执行 ./autogen.sh
FAQ:
报错:
makeinfo: Command not found
缺组件安装上去: sudo apt-get install texinfo
5、编译 gettext:v0.21
这个会复杂一点,坑多点。 变量设置:
export NDK_TOOLCHAIN=/home/share/ide/my-android-toolchain64
export PATH=${NDK_TOOLCHAIN}/bin:$PATH
export PREFIX=/home/share/work/prefix
export ANDROID_SYSROOT=${NDK_TOOLCHAIN}/sysroot
export SYSROOT=$ANDROID_SYSROOT
export ANDROID_HOST=aarch64-linux-android
export ANDROID_BUILD=linux-x86_64
export ANDROID_ARCH=arm64
export ANDROID_VERSION=21
export ANDROID_TOOLCHAIN_VERSION=4.9
export LDFLAGS="-Wl,-rpath-link=-I${SYSROOT}/usr/lib -L${SYSROOT}/usr/lib -L${NDK_TOOLCHAIN}/lib"
export LIBS="-lc"
export BUILD_SYS=x86_64-linux-gnu
export CFLAGS="--sysroot=${SYSROOT} -I${SYSROOT}/usr/include -I${PREFIX}/include -fPIE -DANDROID -Wno-multichar"
./configure --build=${BUILD_SYS} --prefix=${PREFIX} --host=aarch64-linux-android --disable-rpath --disable-libasprintf --disable-java --disable-native-java --disable-openmp --disable-curses
FAQ:
1、报错 头文件里的memcopy的static 有问题 删除static
2、make成功,make install 失败 cannot find -lgettextlib 参考解答:https://developer.aliyun.com/article/57597 这个错误在编译gettext时不会发生,而会在执行make install的时候发生,它会找不到libgettextlib.a这个库。 当编译成功时,libgettextlib.a这个库是会生成的,这个库的路径在这个目录中: <gettext源码目录>/gettext-tools/gnulib-lib/.libs/,将这个路径添加到configure命令行的库搜索路径中,上面的configure的命令行选项中设置了这个目录。
export localgnulib=/home/share/work/lib_reference/gettext/gettext-0.21/gettext-tools/gnulib-lib/.libs/
export LDFLAGS="-Wl,-rpath-link=-I${SYSROOT}/usr/lib -L${SYSROOT}/usr/lib -L${NDK_TOOLCHAIN}/lib -L${localgnulib}"
./configure --build=${BUILD_SYS} --prefix=${PREFIX} --host=aarch64-linux-android --disable-rpath --disable-libasprintf --disable-java --disable-native-java --disable-openmp --disable-curses
重新make clean。再configure 一次 再走一遍流程
./configure --build=${BUILD_SYS} --prefix=${PREFIX} --host=aarch64-linux-android --disable-rpath --disable-libasprintf --disable-java --disable-native-java --disable-openmp --disable-curses
6、编译glib
2.5.83目录新建一个缓存文件,比如android.cache,添加进文件
glib_cv_long_long_format=ll
glib_cv_stack_grows=no
glib_cv_sane_realloc=yes
glib_cv_have_strlcpy=no
glib_cv_va_val_copy=yes
glib_cv_rtldglobal_broken=no
glib_cv_uscore=no
glib_cv_monotonic_clock=no
ac_cv_func_nonposix_getpwuid_r=no
ac_cv_func_posix_getpwuid_r=no
ac_cv_func_posix_getgrgid_r=no
glib_cv_use_pid_surrogate=yes
ac_cv_func_printf_unix98=no
ac_cv_func_vsnprintf_c99=yes
ac_cv_func_realloc_0_nonnull=yes
ac_cv_func_realloc_works=yes
设置变量
export NDK_TOOLCHAIN=/opt/android/android-ndk-toolchain
export PATH=${NDK_TOOLCHAIN}/bin:$PATH
export PREFIX=/home/share/work/prefix
export ANDROID_SYSROOT=${NDK_TOOLCHAIN}/sysroot
export SYSROOT=$ANDROID_SYSROOT
export ANDROID_HOST=aarch64-linux-android
export ANDROID_BUILD=linux-x86_64
export ANDROID_ARCH=arm64
export ANDROID_VERSION=21
export ANDROID_TOOLCHAIN_VERSION=4.9
export LIBS="-lc -lz -lffi"
export BUILD_SYS=x86_64-linux-gnu
$ ./autogen.sh
注意: 这里执行autogen.sh 自动生成一次配置,提示一些错误,只要不是配置出错是可以进行下一步的比如: If you meant to cross compile, use --host'. See config.log’ for more details
#加上一些编译变量,之所以在这里加 是区别于上面的纯粹变量。还有比较autogen.sh比较好排错
export LIBFFI_CFLAGS="-I/home/share/work/prefix/include"
export LIBFFI_LIBS="-L/home/share/work/prefix -lffi"
export ZLIB_CFLAGS="-I/home/share/ide/my-android-toolchain64-n16/sysroot/usr/include"
export ZLIB_LIBS="-lz -L/home/share/ide/my-android-toolchain64-n16/sysroot/usr/lib"
export CFLAGS="-D__ANDROID_API__=21 --sysroot=${SYSROOT} -I${SYSROOT}/usr/include -I${PREFIX}/include -I/home/share/ide/my-android-toolchain64-n16/sysroot/usr/include -fPIE -DANDROID -Wno-multichar"
export LDFLAGS="-Wl,-rpath-link=-I${SYSROOT}/usr/lib -L${SYSROOT}/usr/lib -L${PREFIX}/lib -L${NDK_TOOLCHAIN}/lib -L/home/share/ide/my-android-toolchain64-n16/sysroot/usr/lib"
#这个变量写了容易出错,不是必须的不要写
#export CPPFLAGS="--sysroot=${SYSROOT} -I${SYSROOT}/usr/include -I${NDK_TOOLCHAIN}/include/c++/ -DANDROID -DNO_XMALLOC -mandroid"
说明: LIBFFI_CFLAGS, LIBFFI_LIBS 对应libffi ZLIB_CFLAGS, ZLIB_LIBS 对应libz 这两组变量是要设置的,不设置就会出现faq里的问题。 谷歌百度都是叫设置这2组变量。但是我之前一直都是懵逼的,为什么要设置。 直到看了configure -h 里面有说明这2组变量就是给libffi和libz做关联用的 所以要在 ./configure 执行前设置好 这两组变量提前设置好就不需要修改makefile 等一系列烧操作了
配置:
4、配置,成功则make,成功则make install
./configure --build=${BUILD_SYS} --host=aarch64-linux-android --prefix=${PREFIX} \
--disable-dependency-tracking --cache-file=android.cache --enable-included-printf --enable-static --with-pcre=no --enable-libmount=no
FAQ
参考:https://www.i4k.xyz/article/kuidaitui3165/112197928
错误一:
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_sint32@LIBFFI_BASE_7.0'
./.libs/libgobject-2.0.so: undefined reference to `ffi_prep_cif@LIBFFI_BASE_7.0'
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_pointer@LIBFFI_BASE_7.0'
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_uint32@LIBFFI_BASE_7.0'
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_void@LIBFFI_BASE_7.0'
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_uint64@LIBFFI_BASE_7.0'
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_sint64@LIBFFI_BASE_7.0'
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_double@LIBFFI_BASE_7.0'
./.libs/libgobject-2.0.so: undefined reference to `ffi_call@LIBFFI_BASE_7.0'
错误二:
./.libs/libgio-2.0.so: undefined reference to `inflate'
./.libs/libgio-2.0.so: undefined reference to `deflateReset'
./.libs/libgio-2.0.so: undefined reference to `deflate'
./.libs/libgio-2.0.so: undefined reference to `deflateInit2_'
解答: LIBFFI_CFLAGS, LIBFFI_LIBS 对应libffi ZLIB_CFLAGS, ZLIB_LIBS 对应libz 这两组变量先设置好再config就不会有这个问题,也不在需要改Makefile 那是老做法了。
|