Android 交叉编译libimobiledevice
交叉编译基本步骤
自己的项目经验,并不一定适用其他人。 首先 Makefile 基础必须掌握,可以参考GNU make rules
1 准备交叉编译工具链,配置相应的编译环境,依赖库,sysroot,头文件等,最好为该库准备一个 setenv.sh 的脚本。
2 一般开源库都是 cmake 工程,所有编译的第一步都是运行 configure 检查配置。交叉编译的区别是需要指定–host=arm-linux,如果需要指定编译后的存放目录–prefix.具体选项在configure --help
里都有。
3 configure 成功运行后,可能会遇到错误,一般是头文件,库,或者依赖路径不对,版本不够,等等。依次解决就好。
libimobiledevice
libimobiedevice是一个非常有用的库,实现 ios 上的tcp over usb
的基础。
交叉编译 imobiledevice 到安卓
- 准备 android toolchain
直接用 ndk 的 build/tools/直接生成,android 和其他交叉编译平台只是工具链的区别。
./make_standalone_toolchain.py --api 23 --arch arm --install-dir /home/android-toolchain --stl libc++
- configure 脚本
在源码目录,新建 build-android 文件夹 放入如下configure_android
文件 执行它来配置 configure,表示交叉编译,prefix 指定目录,如有其他参数可以通过该脚本转发
../configure \
--host=arm-linux \
--prefix=/home/install-prefix/android \
"$@"
- 配置 gcc 的基本选项
一个准备 enviroment.sh 脚本配置 gcc 的基本选项,很重要。需要配置以下选项。
sysroot
交叉工具链目录(CC CXX AR LD 这些)
pgkconfig
编译参数 CPPFLAG CFLAGS
rpath
#!/bin/sh
export NDK_ROOT=/home/bravo/Android/Ndk/android-ndk-r12b
#to be compatable with , better use android-19
export SYS_ROOT=$NDK_ROOT/platforms/android-19/arch-arm
# generated by ndk standand tools
export TOOLCHAIN_ROOT=/home/android-toolchain
export TOOLCHAIN=$TOOLCHAIN_ROOT/bin/arm-linux-androideabi
#generate all the android libs here
#also other dependency library and header files put here
export INSTALL_PREFIX=/home/install-prefix/android
export PKG_CONFIG_PATH=$INSTALL_PREFIX/lib/pkgconfig
export CC="$TOOLCHAIN-gcc"
export CXX="$TOOLCHAIN-g++"
export CPP="$TOOLCHAIN-gcc -E"
export AR="$TOOLCHAIN-ar"
export LD="$TOOLCHAIN-ld"
export NM="$TOOLCHAIN-nm"
export STRIP="$TOOLCHAIN-strip"
export CPPFLAGS="-I${SYS_ROOT}/include -I${SYS_ROOT}/usr/include -I${INSTALL_PREFIX}/include -I${NDK_ROOT}/sources/android/support/include"
export LDFLAGS="-L. -L${SYS_ROOT}/usr/lib -L${INSTALL_PREFIX}/lib -L${TOOLCHAIN_ROOT}/lib "
export CFLAGS="-lusb1.0 -lc -lm -lz -pie -fPIE -fno-stack-protector -O0 -march=armv7-a -marm -mthumb-interwork -mfloat-abi=softfp -mfpu=neon -Wno-multichar -DHAVE_SYS_UIO_H -DHAVE_PTHREADS -Wno-multichar -DANDROID -Wno-redundant-decls -Wno-shadow ${CPPFLAGS} ${LDFLAGS} -Wl,-rpath=../lib"
#set rpath , don't use LD_LIBRARY_PATH when executing
#export CXXFLAGS="${CFLAGS}"
- 下载及编译相关库
git clone 可以直接拖.编译及依赖顺序是
libxml2 -> libplist -> libusbmuxd -> libimobiledevice -> libideviceinstaller
问题记录
- libxml2 error 1
../runtest.c:200:18: fatal error: glob.h: No such file or directory
找到glob.c glob.h
把 glob.c 放到environment.sh
的INSTALL_PREFIX/lib
把 glob.h 放到 INSTALL_PREFIX/include
按下面命令单独生成 glob.o
$CC ${CFLAGS} -c glob.c
在enviroment.sh
里添加 -L/INSTALL_PREFIX/lib
在configure_android.sh
里添加 LIBS=INSTALL_PREFIX/lib/glob.o
可以弥补找不到 glob 的缺陷 ,binonic c 库相对 glibc 库做了裁剪
- libxml2 error 2
/usr/include/python2.7/pyconfig.h:30:52: fatal error: arm-linux-gnueabi/python2.7/pyconfig.h: No such file or directory
首先添加 sysroot。
add --sysroot=${SYS_ROOT} in CFLAGS in environment.sh
add --with-sysroot=${SYS_ROOT} in configure_android
问题仍然存在,直接下载python2.7-dev
解压:
dpkg -x /python2.7-dev /tmp/deb
把 arm-linxu-gnueabi 的头文件拷贝出来
cp /tmp/deb/usr/include/arm-linux-gnueabi INSTALL_PREFIX/include
- libplist error 1
提示 libxml2.6.28 版本太低,将其升级. 下载2.9.4
解压重编译安装,但是还是报错 直接从可以从.lib/下 得到已经编译好的库 … 拷贝到 INSTALL_PREFIX/lib 下
- libplist error 2
plistutil.o:plistutil.c:function main: error: undefined reference to 'malloc'
plistutil.o:plistutil.c:function main: error: undefined reference to 'strcmp'
错误是没有找到相应的头文件, 因此没有找到符号.
打开 Makfile 发现是 CPPFLAGS 为空 原本以为通过 configure_android 加进去了
最终发现 LIBS 也没加上-lc
干脆修改 environment.sh
将-lc 加到 CFLAGS 将 CPPFLAGS 和 LDFLAGS 都加到 CFLAGS 里
- libusbmuxd error 1
libtool: warning: library '/home/install-prefix/android/lib/libplist.la' was moved.
/bin/sed: can't read /home/bravo/Android/Ndk/android-ndk-r12b/platforms/android-23/arch-arm/home/install-prefix/android/lib/libxml2.la: No such file or directory
libtool: error: '=/home/install-prefix/android/lib/libxml2.la' is not a valid libtool archive
Makefile:420: recipe for target 'libusbmuxd.la' failed
这句话在=/home/install-prefix/android/lib/libplist.la 中出现,很奇怪 =/home/install-prefix/android/lib/libxml2.la 删除掉就好了
- libusbmuxd error 2
/home/install-prefix/android/lib/libusbmuxd.so: error: undefined reference to 'rpl_malloc'
/home/install-prefix/android/lib/libusbmuxd.so: error: undefined reference to 'rpl_realloc'
/home/install-prefix/android/lib/libcrypto.so: error: undefined reference to 'bsd_signal'
在 lib-iphone 下 grep 了下 rpl_malloc 发现是 libusbmuxd 中用到了代替 malloc 的 既然找不到,那就不要编译,重新 config libusbmuxd。 修改 libusbmuxd/build-android/config.h 注释掉即可
//#define malloc rpl_malloc
//#define realloc rpl_realloc
- libimobiledevice error 1
/home/android-toolchain/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lssl
/home/android-toolchain/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lcrypto
这是缺少 openssl 的库,自己就不编译了,网上找了一个
把库放到INSTALL_PREFIX/lib
下
把头文件放到INSTALL_PREFIX/include
下
重新编译,make clean make,只剩下 1 个错误了
- libimobiledevice error 2
/home/install-prefix/android/lib/libcrypto.so: error: undefined reference to 'bsd_signal'
研究了很久! 网上说是 android-19 以上版本,去掉了该符号 只好用 android-19 来做 sysroot;
export SYS_ROOT=$NDK_ROOT/platforms/android-19/arch-arm
- libimobiledevice error 3
运行时,提示找不到 libcrypt.so.1.0.0 看来不要用动态库的好
编译时将 libcrypt.so libssl.so 从 INSTALL_PREFIF/lib 移除
make clean && make
- libidevicefinder error 1
../../src/ideviceinstaller.c:52:17: fatal error: zip.h: No such file or directory
找不到 zip 头文件..拷贝 1 个过去 同时把 CFLAGS 里添加-lz
缺乏的是 lzip 只能下载一个了
ndk 编译好的 libzip.a 后放在 INSTALL_PREFIX/lib 下
- usbmuxd error 1
checking for pthread_create, pthread_mutex_lock in -lpthread... no
去掉 configure 关于 lpthread 的检查; 去掉有 pthread_cancel 的调用;binonic C 库里没有这个调用;
congfigure 16435 行 echo “good”
- usbmuxd error 2
还是报错,一堆的定义不一致。 参考这个 commit
- usbmuxd error 3
然后又出现了:
../../src/client.c:175: error: undefined reference to 'rpl_malloc'
../../src/client.c:179: error: undefined reference to 'rpl_malloc'
../../src/client.c:182: error: undefined reference to 'rpl_malloc'
这个前面已经遇到过了。
- usbmuxd error 4
/home/android-toolchain/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lusb-1.0
../../src/usb.c:84: error: undefined reference to 'libusb_cancel_transfer'
../../src/usb.c:89: error: undefined reference to 'libusb_cancel_transfer'
找不到 libusb-1.0, 加 1 个即可
- runtime error
最后的最后,在 android 设备实测,发现所有 bin 都跑不起来!用 1 个 test 发现是参数-nostdlib 搞的鬼。
-nostdlib
作用:
不连接系统标准启动文件和标准库文件,只把指定的文件传递给连接器。这个选项常用于编译内核、bootloader 等程序,它们不需要启动文件、标准库文件。
去掉重新编译 ok!
执行 ideviceinfo 返回了基本信息,大工告成。
相信能交叉编译这个库以后,没有什么库编译不了了。