Android NDK链接静态库时出现未定义符号错误求助
Android SDL项目链接Zig静态库出现
undefined symbol: appInit问题 我用SDL仓库提供的Gradle项目做Android构建,单独构建时SDL功能正常,但链接Zig编写的应用逻辑静态库时遇到错误。
项目目录结构
app/jni/src/arm64-v8a/libsdl-test-arm64-v8a.a app/jni/src/armeabi-v7a/libsdl-test-armeabi-v7a.a app/jni/src/x86/libsdl-test-x86.a app/jni/src/x86_64/libsdl-test-x86_64.a app/jni/src/Android.mk app/jni/src/main.c // 调用静态库中定义的appInit app/jni/src/sdl-test.h // 声明void appInit();
构建错误信息
ld: error: undefined symbol: appInit >>> referenced by main.c:5 (jni/src/main.c:5) >>> /Users/mak/dev/zig/sdl-test/android/android-template/app/build/intermediates/cxx/Debug/29445a3u/obj/local/arm64-v8a/objs-debug/main/main.o:(main)
已确认信息
用file命令验证了静态库架构匹配目标平台,以arm64-v8a为例:
libsdl-test-arm64-v8a.a.o: ELF 64-bit LSB relocatable, ARM aarch64, version 1 (SYSV), with debug_info, not stripped
问题原因及解决方案
1. 修正Zig代码的符号导出(核心问题)
Zig默认的函数链接约定不兼容C,会对符号名做特殊修饰,导致C代码无法识别。需要在Zig代码中明确指定C链接约定导出appInit函数:
// 方式1:直接用extern "C"声明 extern "C" fn appInit() void { // 你的应用逻辑代码 } // 方式2:结合export关键字明确导出 extern "C" export fn appInit() void { // 你的应用逻辑代码 }
修改后重新编译Zig静态库。
2. 检查Android.mk的链接配置
确保Android.mk中针对不同ABI正确引入对应的静态库,添加如下配置:
# 根据目标ABI选择对应的静态库 ifeq ($(TARGET_ARCH_ABI),arm64-v8a) LOCAL_LDFLAGS += $(LOCAL_PATH)/arm64-v8a/libsdl-test-arm64-v8a.a else ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) LOCAL_LDFLAGS += $(LOCAL_PATH)/armeabi-v7a/libsdl-test-armeabi-v7a.a else ifeq ($(TARGET_ARCH_ABI),x86) LOCAL_LDFLAGS += $(LOCAL_PATH)/x86/libsdl-test-x86.a else ifeq ($(TARGET_ARCH_ABI),x86_64) LOCAL_LDFLAGS += $(LOCAL_PATH)/x86_64/libsdl-test-x86_64.a endif
同时确认LOCAL_SRC_FILES包含main.c,LOCAL_INCLUDES正确指向头文件所在目录。
3. 验证符号导出正确性
用nm命令检查静态库中的符号是否为C风格的appInit:
nm -D libsdl-test-arm64-v8a.a | grep appInit
如果输出显示T appInit,说明符号正确导出;如果是带Zig修饰的长命名(如_ZN...appInit...),则说明链接约定仍未修正。
内容的提问来源于stack exchange,提问作者Makoren
相关产品推荐
相关产品推荐

