[Android][Google Play]Support 64-bit architectures采坑(一)

项目jni代码比较旧,好几年没维护了……
1、项目采用ndk-build编译方式
2、项目使用Android.mk、Application.mk
3、修改Application.mk中的APP_ABI

APP_ABI := armeabi-v7a arm64-v8a

4、ndk-build NDK_DEBUG=1

error: invalid argument '-std=gnu99' not allowed with 'C++'

5、修改Android.mk,移除’-std=gnu99’部分,继续编译,卡在了libyuv
6、关于libyuv与libjpeg的问题。。。这是一个超级大坑,因为最新的GitHub源代码采用了cmake的方式,于是单独编译了对应版本的so动态库,可是libyuv死活找不到部分jpeg的函数符号

zeonadmindeMac-mini-2:build zeonadmin$ make
[ 49%] Built target yuv
[ 51%] Built target yuvconvert
[ 52%] Linking CXX shared library libyuv.so
/Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:78: error: undefined reference to 'jpeg_std_error'
/Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:89: error: undefined reference to 'jpeg_CreateDecompress'
/Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:0: error: undefined reference to 'jpeg_resync_to_restart'
/Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:96: error: undefined reference to 'jpeg_destroy_decompress'
/Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:121: error: undefined reference to 'jpeg_read_header'
/Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:241: error: undefined reference to 'jpeg_abort_decompress'
/Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:516: error: undefined reference to 'jpeg_start_decompress'
/Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:542: error: undefined reference to 'jpeg_read_raw_data'
/Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:526: error: undefined reference to 'jpeg_abort_decompress'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [libyuv.so] Error 1
make[1]: *** [CMakeFiles/yuv_shared.dir/all] Error 2
make: *** [all] Error 2

用ndk的nm查看符号,全部都在,卧槽不懂了。。。
只好单独将libyuv用单个android studio project的jni来build,结果就成功了

[armeabi-v7a] Gdbserver      : [arm-linux-androideabi] libs/armeabi-v7a/gdbserver
[armeabi-v7a] Gdbsetup       : libs/armeabi-v7a/gdb.setup
[armeabi-v7a] Install        : libjpeg.so => libs/armeabi-v7a/libjpeg.so
[armeabi-v7a] Install        : libyuv.so => libs/armeabi-v7a/libyuv.so

思考了一下原因,用的ndk都是来源AndroidStudio的ndk,TOOLCHAIN应该都是clang…
使用make VERBOSE=1 查看具体的链接库信息。。。
无解。。。
****2019年6月10日 周一****
休了一周的年假回来,整个人都通透了,终于发现了原因在build.sh上:

JPEG_SHARED_LIB=${JPEG_LIB_PATH}/libjpeg.so
...
 
cmake -G"Unix Makefiles" \
    -DANDROID_ABI=armeabi-v7a \
    -DANDROID_PLATFORM=android-${ANDROID_VERSION} \
    -DANDROID_TOOLCHAIN=${TOOLCHAIN} \
    -DANDROID_ARM_MODE=arm \
    -DCMAKE_ASM_FLAGS="--target=arm-linux-androideabi${ANDROID_VERSION}" \
    -DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \
    -DCMAKE_C_FLAGS="${CFLAGS} -Wall -Werror -Wno-unused-parameter -fexceptions" \
    -DJPEG_INCLUDE_DIR=${JPEG_INCLUDE_DIR} \
    -DJPEG_LIBRARY=${JPEG_SHARED_LIB} \
    -DJPEG_SHARED_LIB=${JPEG_SHARED_LIB} \
    ../

注意上面的JPEG_SHARED_LIB使用的是通配符变量,这样的写法cmake链接库的时候找不到,必须给动态库写绝对路径…
7、鉴于Android的样例推荐都采用了cmake编译,于是根据原来的Android.mk,重新翻译成CMakeLists.txt,还是很方便的,就是新东西里面的变量、函数不熟,导致试错成本太高,建议从AndroidStudio新建cmake编译的工程样例开始。

Android[Exception][java.lang.UnsatisfiedLinkError]

上篇二维码的应用使用了jni代码,在Nexus5X(Android7.1.1)上会crash,抛出了如下异常:

AndroidRuntime: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[zip file “/data/app/…/base.apk”],nativeLibraryDirectories=[/data/app/…/lib/arm64, /system/fake-libs64, /data/app/…/base.apk!lib/arm64-v8a, /system/lib64, /system/lib64, /vendor/lib64]]] couldn’t find “libxxx.so”
AndroidRuntime: at java.lang.Runtime.loadLibrary…

在apk包里找不到对应的so文件,在指定的目录下也找不到,于是抛出异常;可以看到lib加载的类型是arm64-v8a,的确是没有,我们来看看别人是怎么说的。
http://blog.csdn.net/qiuchangyong/article/details/50040579

11.APP_ABI目前能取得值包括:(1)、32位:armeabi、armeabi-v7a、x86、mips;(2)、64位:arm64-v8a,x86_64, mips64;

12.注意事项:(1)、目前模拟器只有x86_64的没有arm64-v8a的;(2)、在用真机测试armv8-a时,最好先通过adb shell, cat  /proc/cpuinfo ,来查看下真机是否是支持armv8-a;(3)、arm32和arm64有些配置参数不能共存,如-msoft-float仅在arm32位下支持,在arm64位下是不支持的.

13.使用这个命令可以获得本机的arch:adb shell getprop ro.product.cpu.abi

在本机模拟器上运行时,发现也抛出了这个异常,缺少x86_64导致的,顺利解决。