已编辑:帖子末尾的解决方案。
我正在使用 NDK r8d、使用来自 NDK 的示例项目 hello-jni 以及使用 ARM 独立工具链编译的一些静态库为 android 构建一个共享库。
NDK-BUILD 抱怨未定义的引用。查看链接器命令及其输出:
c:/android/ndk/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-
androideabi-g++ -Wl,-soname,libhello-jni.so -shared --sysroot=c:/android/ndk/platforms
/android-9/arch-arm ./obj/local/armeabi/objs-debug/hello-jni/hello-jni.o ./obj/local
/armeabi/libDataProvider.a ./obj/local/armeabi/libPDF.a ./obj/local/armeabi/libMisc.a
./obj/local/armeabi/libNetwork.a ./obj/local/armeabi/libboost_filesystem.a ./obj/local
/armeabi/libcryptoeng.a ./obj/local/armeabi/libcryptopp.a ./obj/local/armeabi
/libMiniSstructs.a ./obj/local/armeabi/libOBSstructs.a ./obj/local/armeabi
/libSerialization.a ./obj/local/armeabi/libstdc++.a ./obj/local/armeabi
/libboost_iostreams.a ./obj/local/armeabi/libboost_thread.a ./obj/local/armeabi/libz.a
./obj/local/armeabi/libboost_system.a -no-canonical-prefixes -Wl,--no-undefined
-Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -lc -lm -o ./obj/local/armeabi/libhello-jni.so
c:/android/ndk/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc
/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local
/armeabi/libNetwork.a(CertificatesManager.o): in function
OBInfo::GetVersionAsNumber():c:\trunk\src\libMisc/obinfo.h:19: error:
undefined reference to 'OBInfo::versionAsNumber'collect2: ld returned 1 exit status
然而,NM 说这个符号实际上是存在的:
$ nm Tests/hello-jni/obj/local/armeabi/libMisc.a --demangle | grep versionAsNumber
00000000 D OBInfo::versionAsNumber
简化的 OBInfo.h:
class OBInfo
{
public:
static uint32_t GetVersionAsNumber() {return versionAsNumber;};
private:
static uint32_t versionAsNumber;
};
简化的 OBInfo.cpp
#include "obinfo.h"
#include "version_info.h"
uint32_t OBInfo::versionAsNumber = VERSION_AS_NUMBER;
如果我删除 -Wl,--no-undefined 链接器没有错误结束。为什么 LD 找不到符号,但 NM 可以?(顺便说一句:NM 来自 MSYS,而 LD 来自工具链)
编辑:我解决了在 Android.mk LOCAL_STATIC_LIBRARIES 变量中更改静态库顺序的问题。我还重新编译了一些预构建的库,因为有些是在没有优化 -O0 的情况下编译的,而另一些是 -O2 优化的。