AOSP 7.1中链接预编译共享库出现未定义引用问题
解决AOSP 7.1中集成NDK预编译库的未定义引用问题
看了你遇到的困境,这是在AOSP里集成NDK生成的预编译库时非常常见的符号链接问题,我帮你梳理几个关键排查点和解决方案:
1. 先确认预编译库的ABI与AOSP编译目标完全匹配
你提到设备是arm64-v8a,但要同时确保两个层面的匹配:
- CMake生成环节:虽然你的命令指定了
-DANDROID_ABI="arm64-v8a",但要去生成产物目录(比如build/outputs/arm64-v8a)确认库文件确实是对应架构的,避免CMake因为环境问题 fallback 到其他ABI。 - AOSP编译环节:编译AOSP模块时要显式指定目标架构,比如执行编译命令时加上:
防止AOSP默认编译其他架构导致库与模块不兼容。make TARGET_ARCH=arm64 TARGET_ARCH_VARIANT=armv8-a
2. 修正预编译库模块的路径配置
你当前的路径写法lib/../libdump_android.so很容易出错,应该基于LOCAL_PATH使用清晰的相对路径。比如如果预编译库放在模块目录下的libs/arm64-v8a/,修改预编译模块的Android.mk:
include $(CLEAR_VARS) LOCAL_MODULE := libdump_android # 基于LOCAL_PATH的相对路径,同时区分ABI ifeq ($(TARGET_ARCH_ABI),arm64-v8a) LOCAL_SRC_FILE := libs/arm64-v8a/libdump_android.so endif LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/dump include $(PREBUILT_SHARED_LIBRARY)
3. 解决符号可见性问题(核心!)
NDK默认会开启-fvisibility=hidden编译选项,如果你的DumpAndroid类没有显式导出符号,AOSP链接时会找不到这些函数。需要修改代码:
- 在
dump_android.h中添加导出宏:#include <iostream> // 根据编译动态/静态库切换导出属性 #ifdef BUILD_DUMP_ANDROID_SHARED #define DUMP_ANDROID_EXPORT __attribute__((visibility("default"))) #else #define DUMP_ANDROID_EXPORT #endif class DUMP_ANDROID_EXPORT DumpAndroid { public: DumpAndroid(); ~DumpAndroid() = default; void scream(void) const; }; - 在CMakeLists.txt中添加编译定义,确保生成库时导出符号:
add_compile_definitions(BUILD_DUMP_ANDROID_SHARED)
4. 修正使用预编译库的模块配置
- 如果使用动态预编译库:你当前的
LOCAL_SHARED_LIBRARIES := liblog libdump_android是正确的,但要确保预编译模块的Android.mk已经被主模块正确引入(比如用include语句)。 - 如果切换为静态预编译库:需要同时修改两处:
- 预编译模块的结尾改为
include $(PREBUILT_STATIC_LIBRARY) - 使用模块的
LOCAL_SHARED_LIBRARIES替换为LOCAL_STATIC_LIBRARIES := liblog libdump_android
- 预编译模块的结尾改为
5. 验证预编译库的符号是否存在
用NDK的nm工具检查库文件是否包含目标符号,比如:
~/Android/Ndk/android-ndk-r19c/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-nm -D libdump_android.so | grep DumpAndroid
如果能看到DumpAndroid::DumpAndroid()和DumpAndroid::scream() const的符号输出,说明库的符号是正常的;如果看不到,回到第3步检查符号导出配置。
最后再核对头文件路径
你的LOCAL_C_INCLUDES := $(LOCAL_PATH)/include,而dump.h里用了#include <dump_android.h>,要确保include目录下确实存在dump_android.h,或者调整LOCAL_EXPORT_C_INCLUDE_DIRS的路径,让依赖模块能正确找到头文件。
内容的提问来源于stack exchange,提问作者Flamur Berisha
相关产品推荐
相关产品推荐

