基于 Linux 主机上构建的 Android 共享库无法与 Windows 主机上的库构建正确链接

Android shared library built on linux host doesn't link properly with library build on Windows host

本文关键字:构建 主机 Windows 链接 共享 Linux Android 基于      更新时间:2023-10-16

我正在使用Windows上的Android NDK将一组几个C++库编译到arm-v7a。在大多数情况下,我使用ndk构建进行编译。然而,我正在使用的一个库(我们称之为libproblem.so)有一个相当复杂的makefile,所以我使用ajb工具(https://subversion.assembla.com/svn/ajb-tools/trunk/android/android-cross/android-cross)调用makefile在Linux上构建该库。两者都使用相同的NDK版本。

我对android交叉脚本中的默认值进行了一些更改,以匹配我的Application.mk,包括:

export ANDROID_GCCVER=${ANDROID_GCCVER-4.8}
export ANDROID_PLAT_API_VER=${ANDROID_PLAT_API_VER-10} #not sure what this does...
export ANDROID_PLAT_NDK_VER=${ANDROID_PLAT_NDK_VER-9} #gingerbread
export ANDROID_TUNE=${ANDROID_TUNE-"-mandroid $ANDROID_TUNE_THUMB -mthumb-interwork -Wno-psabi -fpic -funwind-tables -fstack-protector -march=armv7-a -finline-limit=64"}

这似乎工作得很好,并给了我一个库,它对file的输出给了我这个:

../obj/local/armeabi-v7a/libproblem.so: ELF 32-bit LSB shared object, ARM, 
version 1 (SYSV), dynamically linked (uses shared libs), not stripped

然后,我在我的Makefile.mk.中使用以下内容将它与其他库链接起来

include $(CLEAR_VARS)
LOCAL_MODULE := problem
LOCAL_SRC_FILES := $(JNI_PATH)/../libs/prebuilt/$(TARGET_ARCH_ABI)/libproblem.so
include $(PREBUILT_SHARED_LIBRARY)

但是,这会导致链接错误。依赖libproblem的库无法创建共享对象,声明:

d:/Code/project/jni/SomeCode.cpp:191: error: undefined reference to 'Problem::Client::Client(std::shared_ptr<Problem::Data> const&)'

功能当然存在。如果我在MinGW中的libproblem.so上运行nm,我会看到那里的函数(尽管已经损坏)。

我目前唯一的想法是使用两个不同的主机操作系统时出现问题。因为特别奇怪的是,如果我使用linux作为运行ndk构建的主机操作系统,ndk构建会成功地将libproblem.so与我的其他对象链接起来。(请记住,Linux和Windows都有相同的NDK版本,NDKr10b,用于64位主机的32位目标)。

或者我在android交叉脚本中遗漏了一些东西,该脚本以与我的ndk版本不兼容的方式构建该库?

UPDATE:失败的链接命令如下

/c/Android/android-ndk-r10b/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-
x86_64/bin/arm-linux-androideabi-g++ -Wl,-soname,libFinal.so -shared 
--sysroot=c:/Android/android-ndk-r10b/platforms/android-9/arch-arm d:/Code/project
/obj/local/armeabi-v7a/objs/Final/Final.o d:/Code/project/jni/../libs/prebuilt/
armeabi-v7a/libboost_system.a d:/Code/project/jni/../libs/prebuilt/armeabi-
v7a/libboost_date_time.a d:/Code/project/jni/../libs/prebuilt/armeabi-
v7a/libboost_filesystem.a -lgcc d:/Code/project/obj/local/armeabi-v7a/
lib1noproblem.so d:/Code/project/obj/local/armeabi-v7a/lib2noproblem.so d:/Code/
project/obj/local/armeabi-v7a/libproblem.so d:/Code/project/obj/local/armeabi-
v7a/libgnustl_shared.so -no-canonical-prefixes -march=armv7-a -Wl,--fix-cortex-a8
-Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now  -Lc:/Android/
android-ndk-r10b/platforms/android-9/arch-arm/usr/lib -lm -llog c:/Android/
android-ndk-r10b/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/libsupc++.a 
-lc -lm -o d:/Code/project/obj/local/armeabi-v7a/libFinal.so

如果您能显示最终链接命令及其生成的完整错误消息,那将非常有用。链接ELF库时,库的顺序很重要,未定义的引用可能来自于此。

使用"ndk build V=1"来转储生成命令。