2014-04-13 10 views
24

tl; dr: La domanda è per una spiegazione del perché std::stringstream "fallisce", e perché non riesce nel modo in cui lo fa (per semplicemente non facendo nulla), quando si collega a una libreria condivisa C++ _ ricostruita.NDK Android STL C++ _ condivisa w/risultati LIBCXX_FORCE_REBUILD in std :: stringstream NOP

Un esempio minimo:

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

Quando si compila il progetto con

APP_STL := c++_shared 
LIBCXX_FORCE_REBUILD := true 

L'uscita è Length: 0. Quando si utilizza APP_STL := c++_static o LIBCXX_FORCE_REBUILD := false, le stringstream opere come previsto, con Length: 11 come uscita.

Sto utilizzando molte parti dell'STL e l'unica differenza evidente che ho visto finora è questa silenziosa NOPstringstream. Ho anche provato questo modificando il campione libgl2jni NDK, aggiungendo il file Application.mk come:

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 

Ho provato le varie permutazioni di APP_OPTIM come rilascio/debug, APP_STL come C++ _ condiviso/C++ _ statica e LIBCXX_FORCE_REBUILD come vero/falso, su un Nexus-4, sia con armeabi e armeabi-v7a come bersaglio ABI. Questo è il risultato:

|-------------+-----------+----------------------+---------+------------------| 
| 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]/opt/android-NDK-r9d/sorgenti/CXX-stl/LLVM-libC++/librerie/armeabi/libC++ static.a (ios.o):/tmp/NDK-andrewhsieh/tmp/build-21097/build-libC++/NDK/sorgenti/CXX-stl/LLVM-libC++/libcxx/src/ios.cpp: la funzione std :: _1 :: :: ios_base xalloc() : errore: undefined reference to '__atomic_fetch_add_4'

PS: assicurarsi di fare un ndk-build clean tra questi test.

La domanda: Qualcuno potrebbe dare una certa comprensione sul perché std::stringstream fallisce Date queste circostanze, e perché non riesce da solo facendo un NOP su tutti i dati che viene trasmesso ad esso?

Grazie

risposta

22

non posso rispondere perché il NOP si sta verificando in alcune permutazioni. Ma sono riuscito a scoprire i fallimenti della costruzione.

ero in una situazione peggiore di te. Stavo sperimentando i fallimenti di build relativi alla combinazione dell'uso di C++ _ static e del valore predefinito per LIBCXX_FORCE_REBUILD (false) e non avevo idea del perché.

Grazie a voi per condividere la vostra ricerca sulle varie permutazioni di collegamento tra STL - sono stato in grado di passare direttamente alla documentazione saliente per correggere l'errore di compilazione.

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

Per poter utilizzare libatomic è necessario impostare la vostra NDK_TOOLCHAIN_VERSION a 4.8

+1

stavo avendo un problema simile e aggiungendo che lib ha fatto il trucco per me :) – unbekant

+0

carico libatomic aiutato per la costruzione di target armeabi – Sam

+0

Strano, ma dopo alcune difficoltà ho potuto compilare solo dopo aver aggiunto 'APP_LDFLAGS + = -latomic' LDLIBS non ha funzionato per me. –

2

Si prega di provare questo:

LOCAL_LDFLAGS += -Wl,--gc-sections 

Sembra che il frammento di codice in realtà non denominato atomic_fetch_add(). Con l'opzione --gc-section LD, il linker elimina il codice e i dati inutilizzati dall'eseguibile finale o dalla libreria condivisa. In modo che la dipendenza di atomic_fetch_add() sia rimossa.

Descrizione di "--gc sezioni": https://gcc.gnu.org/onlinedocs/gnat_ugn/Compilation-options.html

Qualche altro infomation: https://code.google.com/p/android/issues/detail?id=68779

+8

Puoi spiegare cosa fanno queste bandiere? La tua risposta deve essere istruttiva, non solo qualcosa da digitare e risolvere il problema. – pedromanoel

+0

@foqq grazie per il collegamento bug con contesto completo. – dcow