如何用CMake将已编译可执行文件正确打包到Android应用中?
问题原因与解决方法
核心原因
Android构建系统(AGP)默认只会自动识别并打包**共享库(SHARED类型)**到APK的/lib/${ANDROID_ABI}目录。你用add_executable(IMPORTED)声明的目标属于可执行文件类型,哪怕后缀是.so,AGP也不会将其纳入自动打包规则。
而用add_executable(hello_world.so hello_world.cpp)能成功打包,是因为CMake编译生成的.so文件会被AGP的默认扫描规则捕获——AGP会把CMake输出目录下/lib/${ANDROID_ABI}路径里的所有.so文件打包,不管它实际是可执行文件还是共享库,这和CMake目标类型无关。
可行解决办法
方法一:伪装成共享库导入
直接用add_library将已编译的可执行文件当作共享库导入,复用你之前成功打包共享库的配置逻辑即可:add_library(hello_world.so SHARED IMPORTED) set_target_properties( hello_world.so PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/libs/${ANDROID_ABI}/hello_world.so)这种方式无需修改可执行文件本身,AGP会正常将其打包到指定目录,运行时行为和原可执行文件完全一致。
方法二:手动指定打包规则
若不想伪装成库,可通过CMake的install命令或Gradle的sourceSets配置主动告诉AGP要打包该文件:- CMake中添加安装规则:
然后在install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/libs/${ANDROID_ABI}/hello_world.so DESTINATION lib/${ANDROID_ABI} )build.gradle的CMake配置中启用安装:externalNativeBuild { cmake { path "CMakeLists.txt" installDir "${buildDir}/install" } } - 或直接在
build.gradle的sourceSets中配置:
这种方式无需在CMake中做导入配置,AGP会自动扫描指定目录下的android { sourceSets { main { jniLibs.srcDirs += "${projectDir}/libs" } } }.so文件并打包。
- CMake中添加安装规则:
内容的提问来源于stack exchange,提问作者Zagorax
相关产品推荐
相关产品推荐

