交叉编译aarch64 Android库时标准库缺失问题排查
问题根源与解决方案
你遇到的核心问题是用错了交叉编译器:Ubuntu系统自带的aarch64-linux-gnu-gcc/g++是为GNU/Linux平台编译程序的工具链,它链接的是GNU C标准库(glibc),对应的库文件是libc.so.6、libstdc++.so.6;而Android使用的是自研的Bionic C标准库,库文件名为libc.so(无版本后缀),且STL默认用libc++而非libstdc++,两者完全不兼容,所以App在Android上找不到这些依赖。
解决步骤
1. 替换为NDK官方适配的工具链
不要使用系统自带的aarch64-linux-gnu工具链,改用Android NDK提供的专用交叉编译器(NDK r21+推荐用clang,gcc已不再维护)。修改你的android.toolchain.cmake:
cmake_minimum_required(VERSION 3.6.0) set(CMAKE_SYSTEM_NAME Android) set(CMAKE_SYSTEM_VERSION 21) # 对应Android API 21,根据APP最低支持版本调整 set(CMAKE_SYSTEM_PROCESSOR aarch64) set(CMAKE_ANDROID_ARCH_ABI arm64-v8a) # 使用NDK自带的clang编译器 set(CMAKE_C_COMPILER "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang") set(CMAKE_CXX_COMPILER "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++") set(CMAKE_ANDROID_NDK /home/ubuntu/Android/Sdk/ndk/21.4.7075529) set(CMAKE_ANDROID_STL_TYPE c++_shared) # 指定使用共享版libc++ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
2. 简化CMake配置(可选但推荐)
NDK自带标准的Android CMake工具链文件,无需手动编写android.toolchain.cmake。直接在CMakeLists.txt中指定NDK路径和相关参数即可:
cmake_minimum_required(VERSION 3.6.0) project(testlibrary) # 直接使用NDK自带的工具链 set(CMAKE_ANDROID_NDK /home/ubuntu/Android/Sdk/ndk/21.4.7075529) set(CMAKE_ANDROID_ARCH_ABI arm64-v8a) set(CMAKE_ANDROID_API 21) # 最低支持的Android版本 set(CMAKE_ANDROID_STL_TYPE c++_shared) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) file(GLOB_RECURSE SOURCE_CPP "src/*.cpp") file(GLOB_RECURSE HEADER "src/*.h") add_library(${PROJECT_NAME} SHARED ${SOURCE_CPP} ${HEADER} ) source_group("Header include" FILES ${HEADER}) source_group("Source src" FILES ${SOURCE_CPP})
3. 修复Gradle配置
- 移除
packagingOptions中关于libc.so.6、libstdc++.so.6等无用配置,这些是GNU/Linux的库,Android不兼容:packagingOptions { pickFirst 'lib/arm64-v8a/libc++_shared.so' // 删掉其他libc.so.6、libstdc++.so.6等配置 } - 确保
externalNativeBuild中的APP_STL与CMake配置一致,推荐用c++_shared:arguments "APP_PLATFORM=android-21", // 和CMake中CMAKE_ANDROID_API一致 "APP_STL=c++_shared", // 移除NDK_TOOLCHAIN_VERSION=gcc,NDK r21+默认用clang,gcc已废弃
4. 验证依赖是否正确
编译完成后,用readelf检查生成的库依赖:
readelf -d libtestlibrary.so | grep NEEDED
正常输出应该是类似:
0x0000000000000001 (NEEDED) Shared library: [libc.so] 0x0000000000000001 (NEEDED) Shared library: [libc++_shared.so]
不再出现libc.so.6或libstdc++.so.6。
关于独立工具链
如果需要更灵活的编译环境,可以使用NDK的make_standalone_toolchain.py生成独立工具链,但上述直接使用NDK自带工具链的方式已经足够解决问题,无需额外生成独立工具链。
内容的提问来源于stack exchange,提问作者Flippy
相关产品推荐
相关产品推荐

