使用NDK与CMake构建Android项目时自定义代码未编译求助
自定义C++代码未被编译的排查与解决
在Ubuntu 23系统中,使用NDK(r25c、r26b版本)、CMake(3.18、3.27版本)及Gradle(7.5.1、8.5版本)构建Android项目时,执行./gradlew assembleDebug显示构建成功并生成APK,但自定义C++代码并未被编译。cmake生成目录下的compile_commands.json存在所有代码的编译命令,手动执行部分命令有效,但找不到自定义代码的编译产物。
使用的CMakeLists.txt文件
cmake_minimum_required(VERSION 3.27) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate") set(COMMON_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../common/src") set(COMMON_HEADERS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../common/include") set(GAME_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../game/src") set(GAME_HEADERS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../game/include") #All files that are compiled file( GLOB_RECURSE COMMON_SRCS ${COMMON_SOURCE_DIR}/*.cc ${COMMON_SOURCE_DIR}/*.cpp ) file( GLOB_RECURSE GAME_SRCS ${GAME_SOURCE_DIR}/*.cc ${GAME_SOURCE_DIR}/*.cpp ) add_library( fc ${COMMON_SRCS} ${GAME_SRCS} ) target_include_directories( fc PUBLIC ${COMMON_HEADERS_DIR} ${GAME_HEADERS_DIR} ) target_compile_features(fc PUBLIC cxx_std_20) target_link_libraries(fc PUBLIC log android )
构建命令行输出
#./gradlew assembleDebug Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. For more on this, please refer to https://docs.gradle.org/8.5/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. BUILD SUCCESSFUL in 2s 34 actionable tasks: 34 executed
使用的build.gradle文件
plugins { id 'com.android.application' } android { defaultConfig { applicationId "com.you.fc" versionCode 1 versionName "1.0" externalNativeBuild { cmake { cppFlags "-fexceptions -frtti -std=c++20" arguments "-DANDROID_STL=c++_shared" abiFilters 'arm64-v8a' } } targetSdk 33 minSdk 22 } splits { abi { enable true reset() include "arm64-v8a" universalApk true } } externalNativeBuild { cmake { version "3.27.4" path file('CMakeLists.txt') } } buildToolsVersion '33.0.0' ndkPath "/home/me/Desktop/dev/android/android-ndk-r25c/" compileSdk 33 namespace 'com.you.fc' } dependencies { implementation 'androidx.appcompat:appcompat:1.5.1' }
问题原因分析
- 库类型未明确指定:CMakeLists.txt中
add_library未声明库类型,默认生成静态库。若该静态库未被其他目标依赖链接,Gradle会判定其无实际用途,跳过编译流程。 - 文件路径匹配失效:
file(GLOB_RECURSE)可能因CMAKE_CURRENT_SOURCE_DIR的实际路径与预期不符,导致../../common/src等路径指向错误,未匹配到真实的C++文件;也可能是代码文件后缀不在.cc/.cpp范围内(如存在.c文件未被包含)。 - Gradle任务依赖异常:CMake生成了编译命令,但Gradle未正确将原生代码编译任务与
assembleDebug任务建立依赖关系,导致原生构建被跳过。 - APK打包遗漏库文件:即使库已编译完成,也可能因Gradle配置问题,未将
.so文件打包进APK。
解决建议
- 修改CMakeLists.txt,明确指定构建动态库:
add_library( fc SHARED ${COMMON_SRCS} ${GAME_SRCS} ) - 在CMakeLists.txt中添加调试输出,验证路径和文件匹配情况:
message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}") message(STATUS "COMMON_SOURCE_DIR: ${COMMON_SOURCE_DIR}") message(STATUS "COMMON_SRCS: ${COMMON_SRCS}") message(STATUS "GAME_SRCS: ${GAME_SRCS}") - 单独触发原生代码构建任务,验证是否生成库文件:
之后查看./gradlew externalNativeBuildDebugapp/build/intermediates/cmake/debug/obj/arm64-v8a/目录下是否存在libfc.so。 - 检查APK内容,确认库文件是否被打包:
unzip -l app/build/outputs/apk/debug/app-arm64-v8a-debug.apk | grep libfc.so
内容的提问来源于stack exchange,提问作者Nathan
相关产品推荐
相关产品推荐

