You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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'
}

问题原因分析

  1. 库类型未明确指定:CMakeLists.txt中add_library未声明库类型,默认生成静态库。若该静态库未被其他目标依赖链接,Gradle会判定其无实际用途,跳过编译流程。
  2. 文件路径匹配失效:file(GLOB_RECURSE)可能因CMAKE_CURRENT_SOURCE_DIR的实际路径与预期不符,导致../../common/src等路径指向错误,未匹配到真实的C++文件;也可能是代码文件后缀不在.cc/.cpp范围内(如存在.c文件未被包含)。
  3. Gradle任务依赖异常:CMake生成了编译命令,但Gradle未正确将原生代码编译任务与assembleDebug任务建立依赖关系,导致原生构建被跳过。
  4. 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 externalNativeBuildDebug
    
    之后查看app/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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 02:13:20