减小 opencv4 动态库 .so 的大小

Reduce opencv4 dynamic lib .so size

本文关键字:so opencv4 动态 减小      更新时间:2023-10-16

我正在尝试减小 android 应用程序的 .so 文件大小,但是当我重新编译动态库时,我的应用程序使用此代码崩溃

java.lang.UnsatisfiedLinkError: No implementation found for long org.opencv.core.Mat.n_Mat() (tried Java_org_opencv_core_Mat_n_1Mat and Java_org_opencv_core_Mat_n_1Mat__).

我也尝试从 src 重新编译,但由于某种原因,当我添加修改根 CMakeLists.txt 文件(此时为 153 行(时,编译失败,因为没有从示例中找到文件。

这是我从 arm64 的静态库中重新编译 .so 的命令

$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++  -fpic --sysroot=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -target aarch64-linux-android21 -shared -Xlinker -soname=libopencv_java4.so -o libopencv_java4.so -Xlinker --no-as-needed -Xlinker --whole-archive -Xlinker libcpufeatures.a -Xlinker libIlmImf.a -Xlinker liblibjasper.a -Xlinker liblibjpeg-turbo.a -Xlinker liblibpng.a -Xlinker liblibprotobuf.a -Xlinker liblibtiff.a -Xlinker liblibwebp.a -Xlinker libquirc.a -Xlinker libtbb.a -Xlinker libtegra_hal.a -Xlinker libopencv_imgcodecs.a -Xlinker libopencv_imgproc.a -Xlinker libopencv_core.a -Xlinker --no-whole-archive -nostdlib++ -llog -ljnigraphics -landroid -lmediandk -lz

生成的 .so 信息

Dynamic section at offset 0x9fabc8 contains 33 entries:
Tag        Type                         Name/Value
0x0000000000000001 (NEEDED)             Shared library: [liblog.so]
0x0000000000000001 (NEEDED)             Shared library: [libjnigraphics.so]
0x0000000000000001 (NEEDED)             Shared library: [libandroid.so]
0x0000000000000001 (NEEDED)             Shared library: [libmediandk.so]
0x0000000000000001 (NEEDED)             Shared library: [libz.so]
0x0000000000000001 (NEEDED)             Shared library: [libm.so]
0x0000000000000001 (NEEDED)             Shared library: [libdl.so]
0x0000000000000001 (NEEDED)             Shared library: [libc.so]
0x000000000000000e (SONAME)             Library soname: [libopencv_java4.so]
0x0000000000000019 (INIT_ARRAY)         0x9e4948
0x000000000000001b (INIT_ARRAYSZ)       216 (bytes)
0x000000000000001a (FINI_ARRAY)         0x9e4a20
0x000000000000001c (FINI_ARRAYSZ)       16 (bytes)
0x0000000000000004 (HASH)               0x1c8
0x000000006ffffef5 (GNU_HASH)           0x5378
0x0000000000000005 (STRTAB)             0x1d230
0x0000000000000006 (SYMTAB)             0xa8d0
0x000000000000000a (STRSZ)              121597 (bytes)
0x000000000000000b (SYMENT)             24 (bytes)
0x0000000000000003 (PLTGOT)             0xa0ae18
0x0000000000000002 (PLTRELSZ)           27888 (bytes)
0x0000000000000014 (PLTREL)             RELA
0x0000000000000017 (JMPREL)             0xb0260
0x0000000000000007 (RELA)               0x3c658
0x0000000000000008 (RELASZ)             474120 (bytes)
0x0000000000000009 (RELAENT)            24 (bytes)
0x000000000000001e (FLAGS)              BIND_NOW
0x000000006ffffffb (FLAGS_1)            Flags: NOW
0x000000006ffffffe (VERNEED)            0x3c5f8
0x000000006fffffff (VERNEEDNUM)         3
0x000000006ffffff0 (VERSYM)             0x3ad2e
0x000000006ffffff9 (RELACOUNT)          16950
0x0000000000000000 (NULL)               0x0

原始 .so 信息

Dynamic section at offset 0x116d898 contains 32 entries:
Tag        Type                         Name/Value
0x0000000000000001 (NEEDED)             Shared library: [libdl.so]
0x0000000000000001 (NEEDED)             Shared library: [libm.so]
0x0000000000000001 (NEEDED)             Shared library: [liblog.so]
0x0000000000000001 (NEEDED)             Shared library: [libjnigraphics.so]
0x0000000000000001 (NEEDED)             Shared library: [libz.so]
0x0000000000000001 (NEEDED)             Shared library: [libc.so]
0x0000000000000001 (NEEDED)             Shared library: [libandroid.so]
0x0000000000000001 (NEEDED)             Shared library: [libmediandk.so]
0x000000000000000e (SONAME)             Library soname: [libopencv_java4.so]
0x0000000000000019 (INIT_ARRAY)         0x11378f0
0x000000000000001b (INIT_ARRAYSZ)       384 (bytes)
0x000000000000001a (FINI_ARRAY)         0x1137a70
0x000000000000001c (FINI_ARRAYSZ)       16 (bytes)
0x0000000000000004 (HASH)               0x228
0x0000000000000005 (STRTAB)             0x3b328
0x0000000000000006 (SYMTAB)             0xc018
0x000000000000000a (STRSZ)              372415 (bytes)
0x000000000000000b (SYMENT)             24 (bytes)
0x0000000000000003 (PLTGOT)             0x117dad8
0x0000000000000002 (PLTRELSZ)           49488 (bytes)
0x0000000000000014 (PLTREL)             RELA
0x0000000000000017 (JMPREL)             0x161668
0x0000000000000007 (RELA)               0x9a138
0x0000000000000008 (RELASZ)             816432 (bytes)
0x0000000000000009 (RELAENT)            24 (bytes)
0x000000000000001e (FLAGS)              BIND_NOW
0x000000006ffffffb (FLAGS_1)            Flags: NOW
0x000000006ffffffe (VERNEED)            0x9a0d8
0x000000006fffffff (VERNEEDNUM)         3
0x000000006ffffff0 (VERSYM)             0x961e8
0x000000006ffffff9 (RELACOUNT)          26157
0x0000000000000000 (NULL)               0x0

好的,最后我通过build_sdk.py脚本减小了opencv的大小,只是在build_library函数的cmake_vars字典中添加了BUILD_LIST="core,imgproc,imgcodecs,java",我也禁用了对"OFF"的INSTALL_ANDROID_EXAMPLES,并将--no_samples_build标志作为命令行选项传递