进入 D:\develop\7zip\p7zip_16.02\CPP\ANDROID\7zr\jni 目录 , 执行如下命令 :
D:\001_Programs\001_Android\002_Sdk\Sdk\ndk\16.1.4479499\ndk-build.cmd
编译要很长时间 , 输出如下结果后 ,
最终在 D:\develop\7zip\p7zip_16.02\CPP\ANDROID\7zr\libs\armeabi-v7a 目录下 , 生成了可执行的 7zr 程序 ;
总共生成了 4 44 种 CPU 架构的 静态库 ; 注意静态库的生成位置 D:\develop\7zip\p7zip_16.02\CPP\ANDROID\7zr\obj\local 目录下 ;
静态库编译出来体积比较大 , 此处 lib7zr.a 静态库有 9.15 MB , 静态库编译时将所有的符号都编译在其中 , 因此比动态库大十几倍 ;
动态库编译后体积较小 , 方便分发 , 常用的第三方服务 , 以及开源代码都使用动态库进行分发 ;
编译过程中其它生成文件如下图 :
编译时遇到的错误 :
【错误记录】Android Studio 导入外部 so 动态库报错 ( java.lang.UnsatisfiedLinkError | 指定 APK 打包动态库的 CPU 架构 )
【错误记录】p7zip 交叉编译 Android 版本 NDK 报错 ( error: case value evaluates to -2 , which cannot be narrowed )
四、Android Studio 导入 lib7zr.a 静态库
主要是修改 CMakeLists.txt 构建脚本 , 其它位置不需要修改 ;
# 指定 CMake 最低版本 cmake_minimum_required(VERSION 3.4.1) # 设置函数库编译 add_library( # 参数 1 : 设置生成的动态库名称 native-lib # 参数 2 : 设置生成的函数库类型 : ① 静态库 STATIC ② 动态库 SHARED SHARED # 参数 3 : 配置要编译的源文件 ../cpp/native-lib.cpp) # 打印日志信息 # ${ANDROID_ABI} 的作用是获取当前的 CPU 指令集架构 # 当本次编译 armeabi-v7a CPU 架构时 , ${ANDROID_ABI} 值为 armeabi-v7a # 当本次编译 x86 CPU 架构时 , ${ANDROID_ABI} 值为 x86 message("CMAKE_SOURCE_DIR : ${CMAKE_SOURCE_DIR}, ANDROID_ABI : ${ANDROID_ABI}") # 到预设的目录查找 log 库 , 将找到的路径赋值给 log-lib # 这个路径是 NDK 的 ndk-bundle\platforms\android-29\arch-arm\usr\lib\liblog.so # 不同的 Android 版本号 和 CPU 架构 需要到对应的目录中查找 , 此处是 29 版本 32 位 ARM 架构的日志库 # # 可以不配置 : # 可以不进行该配置, 直接在后面的 target_link_libraries 中链接 log 也不会出错 find_library( log-lib log) # 打印日志库位置 message(${log-lib}) # 引入静态库 ( 推荐 ) : # ① 参数 1 ( add ) : 设置引入的静态库名称 # ② 参数 2 ( SHARED ) : 设置引入的函数库类型 : ① 静态库 STATIC ② 动态库 SHARED # ③ 参数 3 ( IMPORTED ) : 表示引入第三方静态库 , 导入静态库 , 相当于预编译静态库 # 后续还需要设置导入路径 , 配合该配置使用 add_library( # 设置引入的静态库名称 7zr # 设置引入的函数库类型为静态库 STATIC # 表示引入第三方静态库 IMPORTED) # 设置上述静态库的导入路径 # 设置目标属性参数 : # ① 参数 1 ( add ) : 要设置哪个函数库的属性 # ② 参数 2 ( PROPERTIES ) : 设置目标属性 # ③ 参数 3 ( IMPORTED_LOCATION ) : 设置导入路径 # ④ 参数 4 : 配置静态库的文件路径 set_target_properties( # 设置目标 7zr # 设置属性 PROPERTIES # 导入路径 IMPORTED_LOCATION # ${CMAKE_SOURCE_DIR} 是本 CMakeList.txt 构建脚本的路径 , 是 CMake 工具内置的变量 # Android CMake 也内置了一些变量 , 如 ANDROID_ABI ${CMAKE_SOURCE_DIR}/${ANDROID_ABI}/lib7zr.a) # 打印静态库位置 message("静态库位置 : ${CMAKE_SOURCE_DIR}/${ANDROID_ABI}/lib7zr.a") # 引入动态库 (不推荐) : 使用下面的方式引入动态库会出现于 Android.mk 配置一样的问题 , 6.0 以上的 Android 系统在运行时出现找不到路径的问题 #add_library(add SHARED IMPORTED) # 设置函数库的导入路径 #set_target_properties(add PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a/libadd.so) # 引入动态库 (推荐) : # 设置变量 # CMAKE_CXX_FLAGS 表示会将 C++ 的参数传给编译器 # CMAKE_C_FLAGS 表示会将 C 参数传给编译器 # 参数设置 : 传递 CMAKE_CXX_FLAGS C+= 参数给编译器时 , 在 该参数后面指定库的路径 # CMAKE_SOURCE_DIR 指的是当前的文件地址 # -L 参数指定动态库的查找路径 #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}") # 设置头文件查找路径 include_directories( ../cpp/lib7zr/CPP/7zip/Archive ../cpp/lib7zr/CPP/7zip/Archive/7z ../cpp/lib7zr/CPP/7zip/Archive/BZip2 ../cpp/lib7zr/CPP/7zip/Archive/Common ../cpp/lib7zr/CPP/7zip/Archive/GZip ../cpp/lib7zr/CPP/7zip/Archive/Cab ../cpp/lib7zr/CPP/7zip/Archive/Lzma ../cpp/lib7zr/CPP/7zip/Archive/Tar ../cpp/lib7zr/CPP/7zip/Archive/Zip ../cpp/lib7zr/CPP/7zip/Archive/Split ../cpp/lib7zr/CPP/7zip/Archive/Z ../cpp/lib7zr/CPP/7zip/Compress ../cpp/lib7zr/CPP/7zip/Crypto ../cpp/lib7zr/CPP/7zip/UI/Console ../cpp/lib7zr/CPP/7zip/UI/Common ../cpp/lib7zr/CPP/Windows ../cpp/lib7zr/CPP/Common ../cpp/lib7zr/CPP/7zip/Common ../cpp/lib7zr/C ../cpp/lib7zr/CPP/myWindows ../cpp/lib7zr/CPP ../cpp/lib7zr/CPP/include_windows) # 链接函数库 # 参数 1 : 本构建脚本要生成的动态库目标 # 参数 2 ~ ... : 后面是之前预编译的动态库或静态库 , 或引入的动态库 target_link_libraries( native-lib # 表示 编译 native-lib 模块, 要链接 lib7zr.so 模块 7zr ${log-lib})
五、参考资料
参考资料 :
7-Zip 官网 : https://www.7-zip.org/
Android NDK 编译构建脚本参考文档 :
ndk-build 脚本 : https://developer.android.google.cn/ndk/guides/ndk-build
Android.mk 构建脚本 : https://developer.android.google.cn/ndk/guides/android_mk
Application.mk 构建脚本 : https://developer.android.google.cn/ndk/guides/application_mk
博客资源 : 源码 , 编译后的可执行文件, 在 7zip\p7zip_16.02\CPP\ANDROID\7zr\libs\ 目录下 ;
下载地址 :
GitHub 项目源码 : https://github.com/han1202012/7-Zip