我在尝试编译Android代码时遇到了一个奇怪的问题。我的代码与两个第三方库(libcurl和WebRTC)进行交互,当它进入链接阶段(链接到已编译的共享对象文件)时,它会报告WebRTC中有未定义的函数引用,但libcurl函数没有问题。那我收到未定义错误的例子有:Android NDK共享对象未定义参考错误
WS.cpp:208: error: undefined reference to 'buzz::XmlElement::AddAttr(buzz::QName const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)'
ThirdPartyLibs/WebRTC/src/third_party/android_tools/ndk/sources/cxx-stl/llvm-libc++/libcxx/include/memory:1636: error: undefined reference to 'buzz::QN_MESSAGE'
当我运行nm -C
上的WebRTC库文件,然后grep
结果的功能,该功能被清楚地显示存在和定义(文部分)。
nm -C Android/libs/armv7/libWebRTC.so | grep "AddAttr"
000753e5 t buzz::XmlElement::AddAttr(buzz::QName const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
0007541d t buzz::XmlElement::AddAttr(buzz::QName const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)
nm -C kino/Android/libs/armv7/libWebRTC.so | grep "QN_MESSAGE"
000bfd10 d buzz::QN_MESSAGE
当我说我是链接到的已编译的WebRTC共享库,我应该注意的是,共享库正在使用或者忍者编译静态库文件或目标文件编译。我使用如下的编译:
GCC_armv7=$projectDir/ThirdPartyLibs/WebRTC/src/third_party/android_tools/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
OBJS_armv7="…list of static libraries or object files…”
LDFLAGS="-lc -ldl -lm -fPIC
--sysroot=$projectDir/ThirdPartyLibs/WebRTC/src/third_party/android_tools/ndk/platforms/android-16/arch-arm
-L$projectDir/ThirdPartyLibs/WebRTC/src/third_party/android_tools/ndk/platforms/android-16/arch-arm/usr/lib/"
$GCC_armv7 -v -shared $LDFLAGS -o libWebRTC.so -Wl,-soname=webrtc $OBJS_armv7
当我将代码直接对忍者编译静态库文件,或编译的忍者目标文件链接,我没有得到同样的错误。既然它有效,那么只要链接到其中任何一个都会很好。但是,Java Android开发人员告诉我,虽然Java接受静态库,但Android不支持。我无法想象Java或Android会针对对象文件进行编译。
我还必须强制引用Android.mk文件中的LOCAL_LDLIBS参数中的文件,而不是使用LOCAL_SHARED_LIBRARIES或LOCAL_STATIC_LIBRARIES参数。
当我尝试使用前一种方法时,ndk-build永远不会找到合适的库文件。相反,它似乎使用libcurl和libopenssl库的系统版本。
就像完整性检查一样,我对目标文件和静态库文件运行相同的nm | grep
命令,并将它们与共享目标文件的结果进行比较。下面是静态/对象文件和编译后的文件之间nm –C | grep
结果的比较。
static/object -
00000001 T buzz::XmlElement::AddAttr(buzz::QName const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
shared object -
000753e5 t buzz::XmlElement::AddAttr(buzz::QName const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
从我已经能够收集的nm
输出,有“T”和“t”之间没有什么区别,但我不明白为什么它会在两组之间切换。
我应该注意到,正在使用的gcc(或g ++)编译器是WebRTC下载(commit hash: aad6780e5c25b1622904ef83659461706f6a25db
)提供的相应体系结构的特定gcc/g ++二进制文件。对于ndk-build(ing),我也使用WebRTC下载(src/chromium/src/third_party/android_tools/ndk/ndk-build
)附带的ndk-build二进制文件。
我的问题:我在做什么错误,这样链接对象文件将编译ndk-build Android.mk文件,但链接到共享对象文件将失败,其中一些函数被定义,另一个不是界定?
更新:我刚刚尝试使用ndk-build和一个Android.mk文件而不是gcc/g ++编译这样的文件,并且我得到相同的错误。