Android NDK示例编译失败:API级别未传递至编译环节的解决方法
问题背景
- 编译目标:NDK示例仓库中的native-activity模块
- 使用NDK版本:ndk 25.2.9519653
- 执行的编译命令:
mkdir -p native-activity/app/src/main/cpp/build cd native-activity/app/src/main/cpp/build cmake -DCMAKE_SYSTEM_NAME="Android" -DCMAKE_SYSTEM_VERSION="24" -DCMAKE_ANDROID_NDK="${NDK_HOME}" -DANDROID_NDK="${NDK_HOME}" -DANDROID_PLATFORM=android-24 .. make
编译错误信息
ndk-samples/native-activity/app/src/main/cpp/main.cpp:50:5: error: use of undeclared identifier 'android_set_abort_message'
android_set_abort_message("failed for format error message");native-activity/app/src/main/cpp/main.cpp:127:38: error: 'AChoreographer_getInstance' is unavailable: introduced in Android 24
AChoreographer_postFrameCallback(AChoreographer_getInstance(), Tick, this);ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/bin/../sysroot/usr/include/android/choreographer.h:95:17: note: 'AChoreographer_getInstance' has been explicitly marked unavailable here
AChoreographer* AChoreographer_getInstance() __INTRODUCED_IN(24);
已尝试的无效配置
在示例的CMakeLists.txt中添加以下配置后重新执行cmake、make,问题未解决:
set(CMAKE_SYSTEM_NAME Android) set(CMAKE_SYSTEM_VERSION 24) # API level set(CMAKE_ANDROID_ARCH_ABI arm64-v8a) set(CMAKE_ANDROID_STL_TYPE gnustl_static) set(ANDROID_PLATFORM 24) # API level set(CMAKE_ANDROID_API 24) # API level
解决方案
问题核心是编译时未正确传递目标API级别到编译器,导致__INTRODUCED_IN宏未正确识别API 24的符号。可通过以下步骤解决:
1. 清除旧构建缓存
先删除build目录避免旧配置缓存干扰:
rm -rf native-activity/app/src/main/cpp/build mkdir -p native-activity/app/src/main/cpp/build cd native-activity/app/src/main/cpp/build
2. 正确传递API级别参数
使用NDK官方提供的工具链文件,确保API级别参数被正确识别:
cmake -DCMAKE_TOOLCHAIN_FILE="${NDK_HOME}/build/cmake/android.toolchain.cmake" \ -DANDROID_PLATFORM=android-24 \ -DANDROID_ABI=arm64-v8a \ .. make
3. 修正CMakeLists.txt配置
如果要在CMakeLists.txt中配置,采用NDK官方推荐的方式,避免冲突变量:
cmake_minimum_required(VERSION 3.18.1) project(native-activity) # 指定NDK工具链文件 set(CMAKE_TOOLCHAIN_FILE "${NDK_HOME}/build/cmake/android.toolchain.cmake") # 目标API级别 set(ANDROID_PLATFORM android-24) # 目标ABI set(ANDROID_ABI arm64-v8a) # 使用LLVM libc++(gnustl已废弃) set(ANDROID_STL c++_static) add_library(native-activity SHARED main.cpp) target_link_libraries(native-activity android log)
关键说明
android_set_abort_message和AChoreographer_getInstance均为API 24引入的符号,NDK通过__INTRODUCED_IN宏控制可见性,只有目标API级别≥24时才会启用这些符号。- 不要同时设置
CMAKE_SYSTEM_VERSION和ANDROID_PLATFORM,两者可能冲突,优先使用ANDROID_PLATFORM。 - gnustl在NDK r18及之后版本已被废弃,建议改用LLVM的libc++(即
c++_static或c++_shared)。
内容的提问来源于stack exchange,提问作者chugadie

