2016-01-13 25 views
5

Ho un probe di configurazione che determina quali flag passare a g ++ in base alla piattaforma e alla versione. In genere utilizzo una versione successiva di gcc rispetto alla versione di installazione nativa per accedere alle funzionalità di C++ 14. Su piattaforme precedenti questo significa che devo aggiungere -D_GLIBCXX_USE_CXX11_ABI = 0 per usare il vecchio C++ ABI o non posso collegarmi con le versioni host delle librerie C++. Tuttavia alcune piattaforme più recenti utilizzano il nuovo ABI, nel qual caso è richiesto -D_GLIBCXX_USE_CXX11_ABI = 1 (o nulla).Come sondare l'ABI C++ utilizzato dalla versione di sistema di gcc sulla piattaforma di destinazione

Posso farlo in base alla versione della piattaforma di destinazione (ovvero l'output di lsb_release -a) ma mi piacerebbe un metodo più generale.

Penso di essere a metà strada con la compilazione di un programma ciao C++ con il compilatore nativo (al contrario di quello successivo) ma non riesco a capire come analizzare la versione ABI. E.g.

 
>strings hello | grep ABI 
.note.ABI-tag 
>strings hello | grep CXX 
GLIBCXX_3.4 

o in modo simile sulla versione di libstdC++ utilizzata dal programma hello probe.

 
ldd ./hello | grep stdc++ | sed -e 's_.* /_/_' | cut -f 1 -d' ' |xargs strings | grep 

Qualcuno ha suggerimenti migliori?

aggiornamento: In effetti non ho bisogno di farlo affatto. Il mio vero problema era che avevo una versione precedente di libstdC++. La compilazione ha rilevato una versione 6.0.20 e il runtime ne ha trovato uno incompatibile 6.0.19 (o possibilmente il visto). Avevo un simbolo non risolto che ho erroneamente attribuito alla versione ABI. Contrariamente alla credenza popolare, le versioni minori di libstdC++ non sono sempre compatibili con i binari. La mia intenzione è sempre quella di usare la stessa identica versione al momento dell'esecuzione e della compilazione (se non si utilizza quella nativa dell'host).

+0

Non ho risposto alla domanda ma avendo risolto il mio problema la risposta non è più importante per me. Questa domanda può essere chiusa. –

+1

libstdC++ è compatibile con le versioni precedenti, non sono nemmeno sicuro che seguano alcuna forma di versioning semantico. Scommetto che se ci si collegasse con 6.0.19 e si eseguisse il codice risultante con 6.0.20, funzionerebbe perfettamente. – rubenvb

+0

Anche se è destinato a essere vero. Puoi ancora avere problemi. Ho rotto alcuni programmi (interni) usando una versione successiva della libreria che era bug incompatibile in qualche modo sottile. Non vorrei rischiare di rompere un programma di sistema in questo modo in quanto sarebbe molto difficile eseguire il debug. Vedi anche http://stackoverflow.com/questions/25979778/forcing-or-preventing-use-of-a-particular-minor-version-of-libstdc –

risposta

0

Contrariamente alla credenza popolare, le versioni secondarie di libstdC++ non sono sempre compatibili con i binari.

Non sono binari compatibili in entrambe le direzioni. libstdC++. so.6.0.20 può essere usato quando è richiesto libstdC++. so.6.0.19, ma non viceversa.

Tuttavia, prima di GCC 5 il supporto C++ 11 era ancora sperimentale (cioè in corso di sviluppo) e quindi l'ABI di nuovi componenti C++ 11 non era stabile, quindi non è possibile combinare C++ 11/C++ 14 codice compilato con GCC 4.xe GCC 4.y, o GCC 4 e GCC 5. Per il codice C++ 98 è possibile combinare liberamente & (utilizzare solo il più recente libstdc++.so perché è compatibile solo in una direzione).

I particolari le C++ 11 incompatibilità prima di GCC 5 sono documentate in https://gcc.gnu.org/wiki/Cxx11AbiCompatibility

In ogni caso, per rispondere alla domanda ormai irrilevante:

Penso di essere a metà strada con la compilazione di un programma ciao mondo C++ con il compilatore nativo (in contrasto con il mio più un '), ma non riesco a capire come per sondare la versione ABI

Se è possibile eseguire il compilatore nativo, allora non lo faccio vedi cosa il problema è, basta controllare il valore predefinito della macro:

echo '#include <string>' | g++ -x c++ -E -dM - | fgrep _GLIBCXX_USE_CXX11_ABI 
+0

che è quasi giusto, ma per me usando gcc 4.9.3 o RHEL7 nativa 4.8 la macro per utilizzare sembra essere _GLIBCXX_ABI_TAG_CXX11 o _CXXABI_FORCED_H: ' > echo "# include " | g ++ -x C++ -E -dM - | grep ABI # define _CXXABI_FORCED_H 1 # define __GXX_ABI_VERSION 1002 #define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11"))) ' gcc6 d'altra parte, aggiunge anche: ' # define _GLIBCXX_USE_DUAL_ABI 1 # define _GLIBCXX_USE_CXX11_ABI 1 ' –

+0

No, si tratta di macro completamente diverse. Né GCC 4.9.3 né 4.8 supporta il [Dual ABI] (https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html) introdotto con GCC 5.1, quindi sono ** sempre ** equivalenti a ' _GLIBCXX_USE_CXX11_ABI = 0' –

+0

Se stai usando RHEL dovresti dare uno sguardo a [devtoolset] (https://access.redhat.com/documentation/en/red-hat-developer-toolset/) che ti dà un up-to -date GCC che produce binari che dipendono solo dall'host libstdC++ (e che corrisponde anche alle impostazioni di sistema in termini di 'std :: string' ABI) –