我在嘗試編譯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 ++編譯這樣的文件,並且我得到相同的錯誤。