Bionic是Android平台为了使用C/C++进行原生应用程序开发所有提供的POSIX标准C库。它是Google为Android操作系统提供的BSD标准C库的衍生库。同时Bionic是专门为移动计算而精心设计的,针对移动设备上有限的CPU周期和可用内存进行了裁剪以提高工作效率。
Bionic尽管是C标准库,但是它不以任何方式与其它C库二进制兼容。也就是说Bionic和其它C库不兼容,无法进行交叉编译和相互引用。
Bionic是专门为移动计算而精心设计的,所以Bionic不会支持所有C标准库函数。也就是说它是C标准库的一个子集。如图
// 在configure 19-20行左右添加一句你当前的工具链,这里用的是Android-arm-32位的工具链
CHOST=arm-linux-androideabi
// 编译的产物可以选择本地文件夹
./configure --prefix=/home/timcheng/project/android_bluez5_32bit/bluez5_output
make & make install
//下载最新libffi
wget ftp://sourceware.org/pub/libffi/libffi-3.3.tar.gz
./configure --host=arm-linux-androideabi --prefix=/home/timcheng/project/android_bluez5_32bit/bluez5_output
make & make install
编译新版glib很吉儿麻烦,Be Patient
3.1,编译基础工具
// 编译meson
cd meson-0.53.1
python3 setup.py clean
python3 setup.py build
// install 到本地usr
python3 setup.py install --prefix=/usr --root=/ --single-version-externally-managed
//sed -i -e '1s:.*:#!/usr/bin/env python3:' /usr/bin/meson 好像有时候不会执行这一步,手动添加一下
// 关于ninja和python3,apt安装即可
3.2,初始化交叉编译配置信息
创建一个文件cross-compilation.conf.in
填充基本信息
[binaries]
c = '@TARGET_CROSS@gcc'
cpp = '@TARGET_CROSS@g++'
ar = '@TARGET_CROSS@ar'
strip = '@TARGET_CROSS@strip'
pkgconfig = '@HOST_DIR@/bin/pkgconf'
[properties]
needs_exe_wrapper = true
c_args = [@TARGET_CFLAGS@]
c_link_args = [@TARGET_LDFLAGS@]
cpp_args = [@TARGET_CXXFLAGS@]
cpp_link_args = [@TARGET_LDFLAGS@]
sys_root = '@STAGING_DIR@'
pkg_config_libdir = '@STAGING_DIR@/usr/lib/pkgconfig:@STAGING_DIR@/usr/share/pkgconfig'
[host_machine]
system = 'linux'
cpu_family ='@TARGET_ARCH@'
cpu = '@TARGET_CPU@'
endian = '@TARGET_ENDIAN@'
3.3,配置交叉编译
//配置交叉编译文件
sed -e 's%@TARGET_CROSS@%/opt/android_arm32bit/arm-linux-androideabi/bin/arm-linux-androideabi-%g' \
-e 's%@TARGET_ARCH@%arm%g' -e 's%@TARGET_CPU@%cortex-a9%g' -e 's%@TARGET_ENDIAN@%"little"%g' \
-e 's%@TARGET_CFLAGS@%"-D_LARGEFILE_SOURCE", "-D_LARGEFILE64_SOURCE", "-D_FILE_OFFSET_BITS=64", "-Os"%g' \
-e 's%@TARGET_LDFLAGS@%%g' -e 's%@TARGET_CXXFLAGS@%"-D_LARGEFILE_SOURCE", "-D_LARGEFILE64_SOURCE", "-D_FILE_OFFSET_BITS=64", "-Os"%g' \
-e 's%@HOST_DIR@%/home/timcheng/project/buildroot/output/host%g' \
-e 's%@STAGING_DIR@%/opt/android_arm32bit/arm-linux-androideabi/sysroot%g' \
../cross-compilation.conf.in > ./build/cross-compilation.conf
3.4,编译glib
//配置build信息
PATH="/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/root/.embed" PYTHONNOUSERSITE=y \
meson --prefix=/home/timcheng/project/android_bluez5_32bit/bluez5_output \
--libdir=lib \
--default-library=shared \
--buildtype=release \
--cross-file=/home/timcheng/project/build_bluez5/glib-2.62.4/build/cross-compilation.conf \
-Dinternal_pcre=false \
-Dgio_module_dir=/usr/lib/gio/modules \
-Dinstalled_tests=false \
-Doss_fuzz=disabled \
-Diconv=external \
-Dselinux=disabled \
-Dlibmount=false . ./build
// 开始编译
ninja -j3 -C build/
// install
ninja -j3 -C build/ install
【问题1】
// 这里有个问题meson需要很高版本,所以我采用0.53.1版本,因为16.04最高只能安装0.29.0但是不可行,所以需要自己安装
【问题2】
// 打包到安卓APK,所以去掉了动态库主次版本号,关键字“soname”
// vi build/build.ninja
// LINK_ARGS = -Wl,--as-needed -Wl,--no-undefined -Wl,-O1 -shared -fPIC -Wl,--start-group -Wl,-soname,libglib-2.0.so -Wl,-z,nodelete -Wl,-Bsymbolic-functions /opt/px30/aarch64-linux-android/toolchain/aarch64-linux-android/bin/../sysroot/usr/lib/libpcre.so -pthread -lintl -liconv -lm -Wl,--end-group
// 这里libglib-2.0.so.0改为 libglib-2.0.so
【问题3】
// 部分代码需要剪裁,按报错操作就好
// 需要准备expat
root@ubuntu:/home/timcheng/project/android_bluez5_32bit# cd expat-2.2.9/
// 开始config
root@ubuntu:/home/timcheng/project/android_bluez5_32bit/dbus-1.12.16#
./configure --host=arm-linux-androideabi --prefix=/home/timcheng/project/android_bluez5_32bit/bluez5_output \
PKG_CONFIG_PATH=/home/timcheng/project/android_bluez5_32bit/bluez5_output/lib/pkgconfig \
--exec_prefix=/home/timcheng/project/android_bluez5_32bit/bluez5_output \
CFLAGS=-I/home/timcheng/project/android_bluez5_32bit/bluez5_output/include \
LDFLAGS=-L/home/timcheng/project/android_bluez5_32bit/bluez5_output/lib,/opt/android_arm32bit/arm-linux-androideabi/sysroot/usr/lib \
--enable-abstract-sockets --disable-tests
make
make install
问题【1】:
../dbus/.libs/libdbus-internal.a(dbus-sysdeps-util-unix.o):dbus-sysdeps-util-unix.c:function fill_group_info: error: undefined reference to 'getgrgid_r'
../dbus/.libs/libdbus-internal.a(dbus-sysdeps-util-unix.o):dbus-sysdeps-util-unix.c:function fill_group_info: error: undefined reference to 'getgrnam_r'
root@ubuntu:/home/timcheng/project/android_bluez5_32bit# cd readline-8.0/
./configure --host=arm-linux-androideabi --prefix=/home/timcheng/project/android_bluez5_32bit/bluez5_output
//生成Makefile后,我这边特定需要,需要修改soname
// SHLIB_XLDFLAGS = -L./lib/termcap -Wl,-rpath,$(libdir) -Wl,-soname,`basename $@ $(SHLIB_MINOR)`
// 修改后:SHLIB_XLDFLAGS = -L./lib/termcap -Wl,-rpath,$(libdir) -Wl,-soname,`basename $@`
//SHLIB_LIBVERSION = $(SHLIB_LIBSUFF)
// 修改后:SHLIB_LIBVERSION = $(SHLIB_LIBSUFF)
// 确定一下是不是我需要的不带主次版本号的库
root@ubuntu:/home/timcheng/project/android_bluez5_32bit/bluez5_output/lib# arm-linux-androideabi-readelf -d libreadline.so | grep soname
0x0000000e (SONAME) Library soname: [libreadline.so]
root@ubuntu:/home/timcheng/project/android_bluez5_32bit/bluez5_output/lib#
root@ubuntu:/home/timcheng/project/android_bluez5_32bit# cd bluez-5.54/
./configure --host=arm-linux-androideabi --prefix=/home/timcheng/project/android_bluez5_32bit/bluez5_output \
PKG_CONFIG_PATH=/home/timcheng/project/android_bluez5_32bit/bluez5_output/lib/pkgconfig \
CC="arm-linux-androideabi-gcc \
-L/home/timcheng/project/android_bluez5_32bit/bluez5_output/lib \
-I/home/timcheng/project/android_bluez5_32bit/bluez5_output/include \
-I/home/timcheng/project/android_bluez5_32bit/bluez5_output/include/glib-2.0 \
-I/home/timcheng/project/android_bluez5_32bit/bluez5_output/lib/glib-2.0/include \
-I/home/timcheng/project/android_bluez5_32bit/bluez5_output/include/dbus-1.0 \
-I/home/timcheng/project/android_bluez5_32bit/bluez5_output/lib/dbus-1.0/include" \
--disable-systemd --disable-udev --disable-cups --disable-obex --enable-library
【问题1】:
//configure: error: signalfd support is required
【问题2】:
// fatal error: 'wordexp.h' file not found
//解决方案:找一个wordexp.h复制过去
【问题3】:
// error: static_assert failed "Expression evaluates to false"
//
最后,基于Android8.1编译BlueZ5实属艰难,主要是有了Bluedroid,没必要在Android上使用bluez了。But,依旧可以移植且可以跑起来,毕竟都是linux kernel。以上这套编译方式依然可以适用于其它平台工具链编译BlueZ5,只是Android Bionic工具链存在编译兼容问题等一系列问题。