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

CMake集成Android NDK时find_library()找不到库等配置问题咨询

CMake集成Android NDK常见问题修复方案

find_library()检索失败的根因与修复

你遇到的xxx-NOTFOUND问题核心原因是交叉编译配置的放置顺序错误:所有CMAKE_SYSTEM_NAME、CMAKE_ANDROID_*开头的目标平台相关参数,必须在project()命令调用前设置。
你当前的配置把Android平台参数写在了project()之后,CMake初始化时会默认按当前主机平台(macOS/Windows/Linux)配置库搜索路径、编译工具链,根本不会扫描NDK目录下的库文件,甚至最终编出来的可执行文件是主机架构的,根本无法在Android设备上运行,不只是find_library失效的问题。
修正后的最小可用配置片段如下:

cmake_minimum_required(VERSION 3.23)

# 所有Android交叉编译配置必须放在project()之前
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 21)
set(CMAKE_ANDROID_NDK $ENV{ANDROID_NDK_HOME})
set(CMAKE_ANDROID_STL_TYPE c++_static)
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
# NDK r18+已移除GCC,默认用clang,不需要额外设置CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION

project(playground)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 配置顺序正确后,find_library会自动搜索NDK对应ABI的系统库目录
find_library(mediandk-lib mediandk)
if(NOT mediandk-lib)
    message(FATAL_ERROR "未找到mediandk库,请检查NDK版本与ABI配置")
endif()

add_executable(playground src/main.cpp)
# 链接时使用find_library拿到的库路径
target_link_libraries(playground PRIVATE ${mediandk-lib})

头文件包含路径的规范处理方式

NDK自带的系统公共库(包括mediandk、log、EGL、GLESv2等)的头文件路径完全不需要手动配置:只要交叉编译参数顺序正确,CMake调用NDK的Clang编译器时,会自动把NDK sysroot下的头文件目录加入全局搜索路径,你代码中写的#include <media/NdkMediaCodec.h>可以直接被识别,不需要手动写include_directories指向NDK安装目录。
如果改完配置后IDE出现头文件找不到的红波浪线,只是IDE的CMake索引未刷新,删除build目录重新加载CMake项目即可,不影响实际编译。
只有两种场景需要手动配置头文件路径:

  • 引入非NDK自带的第三方预编译库时,通过target_include_directories把对应库的头文件目录绑定到你的编译target上
  • 使用r16及更早的远古NDK版本时,部分附加库头文件未纳入默认sysroot,可通过NDK内置变量${CMAKE_ANDROID_NDK}/sysroot/usr/include添加路径,新版本NDK无此问题

CMake搭配Android NDK的通用最佳实践

  • 严格遵守配置顺序:所有目标平台、ABI、NDK路径、STL类型相关的交叉编译参数,必须放在project()命令之前,否则会触发各种诡异的路径搜索、架构不匹配问题。
  • 优先使用target粒度的配置:链接库、加头文件路径、加编译选项都用target_link_libraries/target_include_directories/target_compile_options这类target级命令,不要用全局的include_directories/link_libraries,避免多target场景下的配置污染。
  • 不要硬编码绝对路径:NDK路径优先从ANDROID_NDK_HOME环境变量读取,不要写死本地的绝对路径;如果是Android Studio集成的项目,不需要手动写任何CMAKE_ANDROID_*参数,Gradle会自动把所有交叉编译配置传给CMake,你只需要编写模块自身的源文件、依赖逻辑即可。
  • 系统库链接按需选择写法:NDK自带的系统库,既可以直接在target_link_libraries里写库名(比如mediandk/log/android),也可以用find_library拿到路径后再链接,前者写法更简洁,后者可以在配置阶段做库存在性检查,适合需要兼容低版本NDK的场景。
  • 统一STL配置:如果项目依赖多个静态/动态库,所有库必须使用同一种STL实现(要么全用c++_static要么全用c++_shared),否则会出现符号冲突、运行时崩溃问题,无特殊需求优先选c++_static。
  • API级别匹配依赖能力:mediandk的稳定API从Android 21开始提供,你当前设置的CMAKE_SYSTEM_VERSION 21是合理的,如果设到18及以下,就算找到库也会出现链接阶段符号找不到的问题。

内容的提问来源于stack exchange,提问作者DenverCoder21

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:27:22