ndk r19+ 的 llvm 工具链位于 $ndk/toolchains/llvm/prebuilt//bin/,如 linux-x86_64 或 windows-x86_64 目录下;关键可执行文件为带 abi 和 api level 后缀的 clang(如 aarch64-linux-android21-clang),它们是自动配置 target/sysroot 的 wrapper。

NDK r19+ 的 LLVM 工具链在哪
NDK r19 起,LLVM/Clang 是唯一支持的编译器,GCC 已被彻底移除。工具链不再按 ABI 分目录存放,而是统一放在 $NDK/toolchains/llvm/prebuilt/<host>/bin/</host> 下,比如 linux-x86_64 或 windows-x86_64。
关键不是找“LLVM”,而是找带 ABI 和 API level 后缀的 clang 可执行文件:
-
aarch64-linux-android21-clang:编译 arm64-v8a,最低 Android 21 -
armv7a-linux-androideabi21-clang:编译 armeabi-v7a,注意命名中是androideabi,不是android -
i686-linux-android21-clang:x86 -
x86_64-linux-android21-clang:x86_64
这些命令本质是 clang 的 wrapper,自动设置了 --target、--sysroot 和链接路径。手动指定 --sysroot 在 r19+ 通常不必要,反而容易覆盖默认行为。
configure 脚本里怎么传 --host 和 CC
如果你用 autotools(如 FFmpeg、LAME、Erlang),./configure 必须明确告诉构建系统目标平台和编译器。典型写法:
./configure \ --host=aarch64-linux-android21 \ --prefix=$PREFIX \ CC=$TOOLCHAIN/bin/aarch64-linux-android21-clang \ CXX=$TOOLCHAIN/bin/aarch64-linux-android21-clang++ \ AR=$TOOLCHAIN/bin/llvm-ar \ RANLIB=$TOOLCHAIN/bin/llvm-ranlib \ STRIP=$TOOLCHAIN/bin/aarch64-linux-android21-strip \ CFLAGS="-fPIC -O2" \ LDFLAGS="-fPIC"
注意三点:
Android 开发调试技能,通过系统 ADB 工具操作 Android 设备。以下场景必须触发此技能:(1) 直接 ADB 操作——安装 APK、查看设备列表、抓取 logcat 日志、查看已安装应用、清除应用数据、截图、重启设备、拉取/推送文件、查看 CPU/内存/电池信息、adb shell 操作;(2)...
-
--host值必须与编译器前缀一致(如aarch64-linux-android21),不能写成aarch64-linux-android(缺 API level) -
AR和RANLIB必须用llvm-ar/llvm-ranlib,NDK 不再提供 GNU binutils -
CFLAGS中-fPIC对动态库是强制的;静态库虽非强制,但建议加上,避免后续链接时出错
Android.mk / CMakeLists.txt 怎么避开硬编码路径
在 Android Studio 项目中,不要在 Android.mk 或 CMakeLists.txt 里写死 NDK 路径或工具链路径。正确做法是依赖 CMake 自带的 Android toolchain:
- CMake 构建时传入:
-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake - 然后只控制 ABI 和 platform:
-DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-21 -
CMAKE_TOOLCHAIN_FILE内部已封装好所有 clang 调用、sysroot、链接器参数,你只需专注源码逻辑
常见错误:自己在 CMakeLists.txt 里用 set(CMAKE_C_COMPILER ".../aarch64-linux-android21-clang") —— 这会绕过 NDK 的 ABI/platform 校验,导致生成的 so 缺少 ANDROID_API 符号或链接失败。
为什么 clang 报 “undefined reference to ‘__cxa_atexit’”
这是典型的 C++ 运行时链接缺失,尤其在静态链接 libc++ 时容易出现。根本原因是:NDK 默认不链接 libc++_static.a 的完整符号集,而 __cxa_atexit 属于 C++ ABI 初始化部分。
解决方式分场景:
- 用
libc++_shared.so(推荐):确保-DANDROID_STL=c++_shared,并在 APK 中打包该 so;运行时由系统加载 - 强行静态链接:加
-lc++abi -latomic,且顺序不能错:-lc++_static -lc++abi -latomic -lm -lc -llog - 纯 C 项目却用了
.cpp扩展名:改后缀为.c,或显式用clang(而非clang++)编译,避免触发 C++ runtime 链接
这个错误不会在编译阶段报出,往往卡在 ld 阶段末尾,容易误判为源码问题。实际是链接器找不到 C++ ABI 支撑函数 —— 它不在你写的代码里,而在 NDK 提供的运行时库里。










