2014-04-13 46 views
24

TL; DR:的問題是對於爲什麼std::stringstream 「失敗」 的解釋,爲什麼它在它的方式失敗(由什麼都不做),當鏈接到一個重建的C++ _共享庫。的Android NDK STL C++ _共享瓦特/ LIBCXX_FORCE_REBUILD導致的std :: stringstream的NOP

的最小例如:

std::stringstream ss; 
ss << "Hello World"; 
__android_log_print(ANDROID_LOG_INFO, 
        "APP", 
        "Length: %i", ss.str().size()); 

當編譯與

APP_STL := c++_shared 
LIBCXX_FORCE_REBUILD := true 

項目的輸出是Length: 0。當使用APP_STL := c++_staticLIBCXX_FORCE_REBUILD := false時,stringstream按預期工作,其中Length: 11作爲輸出。

我使用了STL的很多部分,迄今爲止我所見到的唯一顯着差異就是這種無聲的NOPstringstream。我還通過修改libgl2jni NDK樣品測試此,加入Application.mk文件爲:

NDK_TOOLCHAIN_VERSION := 4.8 
APP_OPTIM := release 
APP_STL := c++_shared 
APP_ABI := armeabi-v7a #armeabi-v7a x86 
APP_PLATFORM := android-19 
LIBCXX_FORCE_REBUILD := true 

我測試的APP_OPTIM各種排列作爲釋放/調試,APP_STL爲C++ _共享/ C++ _ static,LIBCXX_FORCE_REBUILD爲真/假,在Nexus-4上,armeabiarmeabi-v7a爲目標ABI。這是結果:

|-------------+-----------+----------------------+---------+------------------| 
| ABI   | stl c++_? | LIBCXX_FORCE_REBUILD | optim | Result   | 
|-------------+-----------+----------------------+---------+------------------| 
| armeabi  | static | true     | release | OK    | 
|    | static | true     | debug | OK    | 
|    | static | false    | release | BUILD FAILED [1] | 
|    | static | false    | debug | BUILD FAILED [1] | 
|    | shared | true     | release | NOP    | 
|    | shared | true     | debug | NOP    | 
|    | shared | false    | release | OK    | 
|    | shared | false    | debug | OK    | 
|-------------+-----------+----------------------+---------+------------------| 
| armeabi-v7a | static | true     | release | OK    | 
|    | static | true     | debug | OK    | 
|    | static | false    | release | OK    | 
|    | static | false    | debug | OK    | 
|    | shared | true     | release | NOP    | 
|    | shared | true     | debug | NOP    | 
|    | shared | false    | release | OK    | 
|    | shared | false    | debug | OK    | 
|-------------+-----------+----------------------+---------+------------------| 

[1] /選擇/機器人-NDK-r9d /源/ CXX-STL/LLVM-的libC++ /庫/ armeabi/libc的++ static.a(ios.o):/ tmp/ndk-andrewhsieh/tmp/build-21097/build-libC++/ndk/sources/cxx-stl/llvm-libC++/libcxx/src/ios.cpp:function std :: _1 :: ios_base :: xalloc() :error:undefined reference to'__atomic_fetch_add_4'

PS:確保在這些測試之間做ndk-build clean

問題: 任何人都可以提供一些洞察爲什麼std::stringstream失敗鑑於這些情況,以及爲什麼它通過只是在做對被傳輸到任何數據的NOP失敗?

謝謝

回答

22

我無法回答爲什麼NOP出現在一些排列。但我確實設法瞭解構建失敗。

我的情況比你糟糕。我遇到了與使用C++ _ static和LIBCXX_FORCE_REBUILD(false)的默認值相關的構建失敗,並且不知道爲什麼。

感謝您將您的研究分享到鏈接STL的各種排列 - 我能夠直接跳到顯着的文檔來修復構建錯誤。

It's likely that you need libatomic if you #include . Add "LOCAL_LDLIBS += -latomic" for ndk-build

爲了能夠使用libatomic,您需要將您的NDK_TOOLCHAIN_VERSION設置爲4。8

+1

我有一個類似的問題,並補充說,LIB奏效了,我:) – unbekant

+0

裝載libatomic幫助for armeabi target for – Sam

+0

奇怪,但經過一番苦苦掙扎之後,我只能在加入後才能編譯 'APP_LDFLAGS + = -latomic' LDLIBS並沒有爲我工作。 –

2

請試試這個:

LOCAL_LDFLAGS += -Wl,--gc-sections 

看來,代碼片段並沒有真正被稱爲atomic_fetch_add()。使用--gc-sections LD選項,鏈接器將消除最終可執行文件或共享庫中未使用的代碼和數據。這樣atomic_fetch_add()的依賴關係可能會被刪除。的「--gc截面」

說明: https://gcc.gnu.org/onlinedocs/gnat_ugn/Compilation-options.html

其他一些資料: https://code.google.com/p/android/issues/detail?id=68779

+8

你能解釋一下這些標誌是做什麼的嗎?你的回答需要教學,而不僅僅是打字和解決問題。 – pedromanoel

+0

@foqq感謝與完整上下文的錯誤鏈接。 – dcow