必须使用NDK提供的android.toolchain.cmake工具链文件,仅设CMAKE_SYSTEM_NAME=Android无效;需通过-DCMAKE_TOOLCHAIN_FILE指定路径,并配套设置-DANDROID_ABI、-DANDROID_PLATFORM、-DANDROID_STL三项,且全局ABI与STL必须严格一致。

Android NDK 交叉编译必须用 toolchain 文件,不能只靠 CMAKE_SYSTEM_NAME
直接设置 CMAKE_SYSTEM_NAME=Android 是不够的——CMake 官方 Android 支持依赖完整的 toolchain 文件来覆盖编译器路径、sysroot、ABI、API 级别等。NDK 自带的 build/cmake/android.toolchain.cmake 才是唯一可靠入口。
常见错误:手动指定 CC/CXX 或硬编码 arm-linux-androideabi-g++,会导致链接失败(找不到 libc++_shared.so)或 ABI 不匹配(armeabi-v7a 和 arm64-v8a 混用)。
- 必须通过
-DCMAKE_TOOLCHAIN_FILE=/path/to/ndk/build/cmake/android.toolchain.cmake启动配置 -
-DANDROID_ABI=arm64-v8a、-DANDROID_PLATFORM=android-21、-DANDROID_STL=c++_shared这三项缺一不可 - NDK 路径建议用环境变量
ANDROID_NDK管理,避免硬编码路径
find_package() 在 Android 下容易找不到库,优先用 add_library(... IMPORTED)
Android 的 sysroot 没有标准 /usr/lib 结构,find_package(OpenSSL) 或 find_package(ZLIB) 几乎必然失败——CMake 默认搜索路径不包含 NDK 的 sources 或预构建库目录。
正确做法是显式导入预编译库,尤其对 NDK 自带组件(如 log、android、z):
远程控制 Android 设备,支持截图、自动化操作手机 App 等功能。本应用使用 uiautomator2 作为底层框架,通过 ADB 连接设备,用户无需 Root(1)查看手机屏幕;(2)自动化操作手机 App;(3)远程安装/卸载应用……
立即学习“C++免费学习笔记(深入)”;
add_library(logcat INTERFACE) target_link_libraries(logcat INTERFACE log android z)
若需第三方库(如 OpenSSL),应提前用对应 ABI 编译好 libssl.a 和 libcrypto.a,再通过:
add_library(ssl STATIC IMPORTED)set_target_properties(ssl PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/arm64-v8a/libssl.a)- 确保
target_link_libraries(your_target PRIVATE ssl)中顺序正确(依赖项在后)
ABI 和 STL 必须全局一致,混合使用 c++_shared 和 c++_static 会崩溃
NDK 的 STL 选择不是编译期开关,而是运行时 ABI 约束:c++_shared 要求所有动态库(包括你的 .so 和依赖的第三方 .so)都链接同一份 libc++_shared.so;混用 c++_static 会导致 std::string 内存分配器不兼容,App 启动即 crash。
- 整个项目(包括所有子模块、第三方静态库)必须统一
-DANDROID_STL=c++_shared - 若依赖的第三方 SDK 只提供
c++_static版本,你只能改用c++_static全局切换,并禁用 NDK 的libc++_shared.so加载逻辑 -
ANDROID_CPP_FEATURES=exceptions rtti需显式开启,否则try/catch和dynamic_cast会被静默禁用
调试时 adb logcat 看不到 C++ 日志?检查 __android_log_print 的链接和权限
即使链接了 log 库,__android_log_print(ANDROID_LOG_DEBUG, "tag", "msg") 仍可能无输出——常见原因是目标 target_link_libraries 没包含 log,或 AndroidManifest.xml 中未声明 INTERNET 权限(部分旧版 logcat 实现依赖网络权限)。
- 确认
target_link_libraries(your_lib PRIVATE log)已写入对应 target - 在
CMakeLists.txt中加message(STATUS "Using log: ${ANDROID_NDK}/sources/android/log")验证路径可访问 - 真机调试务必用
adb logcat -s tag过滤,模拟器有时因 SELinux 策略屏蔽 native 日志
ANDROID_ABI 放在 -DCMAKE_TOOLCHAIN_FILE 前面),CMake 也会静默忽略它,最后链接失败才暴露问题。

















