NDK移植编译 android-ndk-r10dNDK基本流程

发布时间:   来源:CSDN  

I. 基本流程

1.设置环境变量


(资料图片)

建议去官网下载最新版本的NDK,老版本很多宏定义缺失,比较麻烦。同时,之前用android-ndk-r10d,需要安装32位库环境。

yum install libstdc++-devel.i686yum install libzip.i686

#!/bin/bash# environment settingexport ANDROID_NDK_PATH=/opt/android-ndk-r14bexport TOOLCHAINS_PATH=${ANDROID_NDK_PATH}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/binexport PATH=${PATH}:${TOOLCHAINS_PATH}export SYSROOT_PATH=${ANDROID_NDK_PATH}/platforms/android-22/arch-armexport LIBSTD_PATH=${ANDROID_NDK_PATH}/sources/cxx-stl/gnu-libstdc++/4.9export CC=arm-linux-androideabi-gccexport CXX=arm-linux-androideabi-g++export AR=arm-linux-androideabi-arexport CFLAGS="-DANDROID -fPIC  -std=c++11 -ffunction-sections -funwind-tables -fstack-protector  -no-canonical-prefixes -fexceptions -frtti -marm -march=armv7-a -mtune=cortex-a8 -mfloat-abi=softfp -mfpu=neon -mthumb -fno-strict-aliasing -finline-limit=64 -Wa,--noexecstack -Wformat -Werror=format-security -g -Wall --sysroot=${SYSROOT_PATH} -I${LIBSTD_PATH}/include -I${LIBSTD_PATH}/libs/armeabi/include -I${ANDROID_NDK_PATH}/sources/android/cpufeatures/"export LDFLAGS="--sysroot=${SYSROOT_PATH} -L${LIBSTD_PATH}/libs/armeabi -lgnustl_shared -lgcc -no-canonical-prefixes -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -lstdc++ -lsupc++ -lc -lm -pthread"

只要事先运行脚本,基本能应对一般的库(包括开源库)的编译。 因为C编译CFLAGS中不存在-std=c++11和-frtti,也不需要STL库gnustl_shared和C++库supc++ ,所以编译纯C库的时候建议移除他们

2.修改Makefile模板,针对EXE情况做特殊处理

GCC=$(CROSS)gccGXX=$(CROSS)g++AR=$(CROSS)arifeq ($(CROSS),arm-linux-androideabi-)ifdef EXE_TARGETCFLAGS += -pie -fPIELDFLAGS += -pie -fPIEendifendif

##3.PTLIB的configure参数 注意,这里的configure文件我做了少量修改。仅个人记录用。

./configure --enable-exceptions --host=armv7-a-android --disable-openssl --disable-shmaudio --enable-shmvideo=no --disable-resolver --enable-serial=no --disable-v4l2

II. 心得

1.主要的头文件目录

/opt/android-ndk-r14b/platforms/android-22/arch-arm/usr/include

/opt/android-ndk-r14b/sources/cxx-stl/gnu-libstdc++/4.9/include

##2.编译错误解决 1)部分原来是/usr/include/sys下的头文件路径可能有变化,直接在incude目录下。 2)出现链接错误时,务必用arm-linux-androideabi-nm检查下是否没实现。存在头文件与库文件不一致的现象。

2.ifaddrs.h不存在

1)使用libuv库内的 android-ifaddrs即可。部分版本可能有坑。 **注意更新,libuv也迭代了几个版本过。

III. ADB使用

以Linux版本的adb为例;Win的版本也可以,但是总体操作Linux下的方便很多

#!/bin/bash#连接adb connect#进入shelladb shell#如果有多个链路,可以这样选择,端口缺省5555adb -s:shell#传输文件adb push 1.txt /storage/emulated/0/#所有动态库需要放置在/system/lib目录下,需要赋予/system目录读写权限,或设置LD_LIBRARY_PATHmount -o remount,rw /system#大多数命令需要busybox驱动,例如vi,ifconfig等busybox vi 1.txt

IV.查看依赖(类似于ldd)

使用readelf函数可以读取动态库或EXE的依赖,下面是示例:

arm-linux-androideabi-readelf -d libjanus_streaming.so Dynamic section at offset 0x25bd8 contains 42 entries:  Tag        Type                         Name/Value 0x00000003 (PLTGOT)                     0x26d80 0x00000002 (PLTRELSZ)                   1256 (bytes) 0x00000017 (JMPREL)                     0x2784 0x00000014 (PLTREL)                     REL 0x00000011 (REL)                        0x22b4 0x00000012 (RELSZ)                      1232 (bytes) 0x00000013 (RELENT)                     8 (bytes) 0x6ffffffa (RELCOUNT)                   145 0x00000006 (SYMTAB)                     0x148 0x0000000b (SYMENT)                     16 (bytes) 0x00000005 (STRTAB)                     0xd88 0x0000000a (STRSZ)                      3651 (bytes) 0x00000004 (HASH)                       0x1bcc 0x00000001 (NEEDED)                     Shared library: [libcurl.so] 0x00000001 (NEEDED)                     Shared library: [libssl.so.1.1] 0x00000001 (NEEDED)                     Shared library: [libcrypto.so.1.1] 0x00000001 (NEEDED)                     Shared library: [libz.so] 0x00000001 (NEEDED)                     Shared library: [libglib-2.0.so.0] 0x00000001 (NEEDED)                     Shared library: [libpcre.so] 0x00000001 (NEEDED)                     Shared library: [libintl.so] 0x00000001 (NEEDED)                     Shared library: [libiconv.so] 0x00000001 (NEEDED)                     Shared library: [libjansson.so] 0x00000001 (NEEDED)                     Shared library: [libgnustl_shared.so] 0x00000001 (NEEDED)                     Shared library: [libstdc++.so] 0x00000001 (NEEDED)                     Shared library: [libc.so] 0x00000001 (NEEDED)                     Shared library: [libm.so] 0x00000001 (NEEDED)                     Shared library: [libdl.so] 0x0000000e (SONAME)                     Library soname: [libjanus_streaming.so.0] 0x0000001a (FINI_ARRAY)                 0x26bcc 0x0000001c (FINI_ARRAYSZ)               8 (bytes) 0x00000019 (INIT_ARRAY)                 0x26bd4 0x0000001b (INIT_ARRAYSZ)               4 (bytes) 0x0000000f (RPATH)                      Library rpath: [/opt/android-libs/lib] 0x00000010 (SYMBOLIC)                   0x0 0x0000001e (FLAGS)                      SYMBOLIC BIND_NOW 0x6ffffffb (FLAGS_1)                    Flags: NOW 0x6ffffff0 (VERSYM)                     0x20f0 0x6ffffffc (VERDEF)                     0x2278 0x6ffffffd (VERDEFNUM)                  1 0x6ffffffe (VERNEED)                    0x2294 0x6fffffff (VERNEEDNUM)                 1 0x00000000 (NULL)                       0x0

V.GDB使用

android下使用gdbserver和gdb配套使用。两个版本必须一致。建议用你NDK目录下的那一对。 整体思路和一般的ARM设备调试类似。

拷贝gdbserver到Android设备上

cd /opt/android-ndk-r14b/prebuilt/android-arm/gdbserveradb push gdbserver /sdcard/share

在Android下启动gdbserver

端口可以随意调整,本文以9999为例

#手工跑./gdbserver 0.0.0.0:9999 ./test_program args#附加进程./gdbserver --attach 0.0.0.0:9999 pid

在调试机上运行gdb 可以在Linux下也可以在Windows下运行,以Linux下运行为例:

cd  /opt/android-ndk-r14b/prebuilt/linux-x86_64/bin#windows下的话就是D:\android-ndk-r14b\prebuilt\windows-x86_64\binadb pull /system/lib/libc.so .adb pull /system/lib/libm.so .……需要把所有依赖的动态库,都放置到当前准备调试的目录下系统相关的动态库也必须补齐,否则堆栈无法正确分析……./gdbtarget remote:9999c

后面就和普通的gdb无差别了

相关文章Related

返回栏目>>