【问题标题】:Android shared library built on linux host doesn't link properly with library build on Windows host在 linux 主机上构建的 Android 共享库无法与在 Windows 主机上构建的库正确链接
【发布时间】:2014-10-13 13:57:30
【问题描述】:

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

我对 android-cross 脚本中的默认值进行了一些更改,以匹配我的 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-build 的主机操作系统,ndk-build 将 libproblem.so 与我的其他对象成功链接。 (请记住,Linux 和 Windows 具有相同的 NDK 版本,NDKr10b,64 位主机的 32 位目标)。

或者我是否遗漏了 android-cross 脚本中的某些内容,该脚本以与我的 ndk-build 版本不兼容的方式构建该库?

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

【问题讨论】:

  • 让我们检查一下函数名是否正确。在 Windows 上构建共享 libDummyProblem.so,它定义了一个虚拟 Problem::Client::Client(std::shared_ptr&lt;Problem::Data&gt; const&amp;),并将其 nm 与在 Linux 上生成的真实 lib 进行比较。

标签: android c++ android-ndk arm armv7


【解决方案1】:

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

使用“ndk-build V=1”转储构建命令。

【讨论】:

  • 已添加。仍然没有解决问题。我暂时使用 ajb-tools 而不是 ndk-build 来构建我的所有代码。
  • 谢谢,假设缺少的函数在 libproblem.so 和 SomeCode.cpp 中的链接命令上出现在它之前的库之一中,它似乎没问题。
  • 您能告诉我们有关 C++ 函数在 libproblem.so 中的可见性,以便链接器似乎找不到吗?确切的(损坏的)名称是什么,它是否公开可见?即这个特定符号的“nm”命令的确切输出是什么?
猜你喜欢
  • 1970-01-01
  • 2020-01-24
  • 1970-01-01
  • 1970-01-01
  • 2021-06-03
  • 2020-04-13
  • 1970-01-01
  • 2011-11-07
  • 1970-01-01
相关资源
最近更新 更多