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

Android NDK下CMake ExternalProject超级构建未执行问题排查

解决Android Studio中CMake ExternalProject未自动构建的问题

你遇到的问题其实是Android Studio的CMake集成机制导致的——默认情况下,Gradle只会触发**直接关联到Android可识别目标(比如共享库.so)**的CMake构建流程,而你的顶层CMake配置里没有生成这样的目标,所以Gradle在完成CMake配置后就停住了,不会调用ninja执行实际的构建任务。

先梳理下现有配置的核心问题:

  • 你的ExternalProject_Add(main)只是定义了一个外部项目,但没有在顶层CMake中创建任何Gradle能识别的构建目标(比如add_library生成的共享库)。
  • Gradle的Android插件会扫描CMake脚本中的add_library输出,只有发现有需要打包到APK的库时,才会完整执行CMake构建流程。

修复步骤

1. 修改顶层CMakeLists.txt,添加触发构建的目标

你需要在顶层CMake中添加一个“占位”的共享库,让它依赖你的main外部项目,这样Gradle就会触发整个构建链。如果你的main项目本身生成了需要打包的.so,也可以直接引用它。

修改后的CMakeLists.txt:

cmake_minimum_required(VERSION 3.4.1)
include(ExternalProject)
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
 set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install)
endif ()

# 转发Android交叉编译参数到外部项目
set(ANDROID_CMAKE_ARGS
 -DANDROID_ABI=${ANDROID_ABI}
 -DANDROID_PLATFORM=${ANDROID_PLATFORM}
 -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
 -DANDROID_NDK=${ANDROID_NDK}
 -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
 -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
 -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
 -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
 -G${CMAKE_GENERATOR})

# 构建Eigen依赖
ExternalProject_Add(eigen
 HG_REPOSITORY https://bitbucket.org/eigen/eigen
 HG_TAG 3.2.10
 CMAKE_ARGS ${ANDROID_CMAKE_ARGS})

# 构建主项目,依赖Eigen
ExternalProject_Add(main
 DEPENDS eigen
 SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/main
 CMAKE_ARGS ${ANDROID_CMAKE_ARGS}
 # 如果你的main项目不需要安装,可以留空INSTALL_COMMAND
 INSTALL_COMMAND "")

# 关键:添加一个空的共享库,让Gradle识别到需要构建的目标
# 这个库会依赖main外部项目,从而触发整个构建流程
add_library(dummy SHARED dummy.cpp)
add_dependencies(dummy main)

# -------- 如果你的main项目生成了实际需要的库(比如libmain.so),可以用下面的配置替换上面的dummy部分 --------
# add_library(main SHARED IMPORTED)
# set_target_properties(main PROPERTIES
#     IMPORTED_LOCATION ${CMAKE_INSTALL_PREFIX}/lib/libmain.so)
# add_dependencies(main main)

注意:你需要在CMakeLists.txt同目录下创建一个空的dummy.cpp文件,内容可以是空的,或者简单写一行:

#include <jni.h>

2. 优化build.gradle配置(可选但推荐)

在defaultConfig的externalNativeBuild中明确指定ABI,避免Gradle默认只构建部分ABI:

apply plugin: 'com.android.application'
android {
 compileSdkVersion 26
 buildToolsVersion "26.0.2"
 defaultConfig {
    externalNativeBuild {
        cmake {
            cppFlags "-std=c++11 -frtti -fexceptions"
            // 明确指定需要构建的ABI
            abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
        }
    }
 }
 externalNativeBuild {
    cmake {
        path "CMakeLists.txt"
    }
 }
}
dependencies {
 implementation fileTree(include: ['*.jar'], dir: 'libs')
 androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
    exclude group: 'com.android.support', module: 'support-annotations'
 })
 implementation 'com.android.support:appcompat-v7:26.+'
 implementation 'com.android.support.constraint:constraint-layout:1.0.2'
 testImplementation 'junit:junit:4.12'
}

原理说明

Gradle的Android插件与CMake的集成逻辑是:只有当CMake脚本中存在add_library创建的共享库目标(因为Android需要打包.so到APK),插件才会调用ninja执行完整的构建。通过添加dummy库并依赖main外部项目,相当于给Gradle一个“信号”:这个库需要构建,而它依赖的所有外部项目也必须先完成构建,这样就会自动触发eigen和main的下载、编译流程了。

内容的提问来源于stack exchange,提问作者tac-eibmoz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:41:47