Quel post sul blog è piuttosto impreciso.
Per quanto ne so, le modifiche C ++ ABI sono state introdotte con tutte le principali versioni di GCC (cioè quelle con diversi componenti del numero di prima o seconda versione).
Non vero. Le uniche modifiche ABI C ++ introdotte da GCC 3.4 sono state retrocompatibili, il che significa che l'ABI C ++ è rimasta stabile per quasi nove anni.
A peggiorare le cose, la maggior parte delle principali distribuzioni Linux utilizza snapshot di GCC e / o patcha le loro versioni di GCC, rendendo praticamente impossibile sapere esattamente con quali versioni di GCC potresti avere a che fare quando distribuisci i binari.
Le differenze tra le versioni patchate delle distribuzioni di GCC sono minori e non cambiano ABI, ad esempio Fedora 4.6.3 20120306 (Red Hat 4.6.3-2) è ABI compatibile con le versioni upstream di FSF 4.6.x e quasi certamente con qualsiasi 4.6. x da qualsiasi altra distribuzione.
Su GNU / Linux le librerie di runtime di GCC usano il controllo delle versioni dei simboli ELF quindi è facile controllare le versioni dei simboli necessarie per oggetti e librerie, e se hai un libstdc++.so
che fornisce quei simboli funzionerà, non importa se è una versione con patch leggermente diversa da un'altra versione della tua distribuzione.
ma nessun codice C ++ (o qualsiasi codice che utilizza il supporto di runtime C ++) può essere collegato dinamicamente se questo deve funzionare.
Anche questo non è vero.
Detto questo, il collegamento statico a libstdc++.a
è un'opzione per te.
Il motivo per cui potrebbe non funzionare se carichi dinamicamente una libreria (usando dlopen
) è che i simboli libstdc ++ da cui dipende potrebbero non essere stati necessari all'applicazione quando l'hai (staticamente) collegata, quindi quei simboli non saranno presenti nel tuo eseguibile. Ciò può essere risolto collegando dinamicamente la libreria condivisa a libstdc++.so
(che è la cosa giusta da fare comunque se dipende da essa.) L'interposizione di simboli ELF significa che i simboli presenti nel tuo eseguibile verranno utilizzati dalla libreria condivisa, ma altri no presente nel tuo eseguibile si troverà in quello a cui libstdc++.so
si collega. Se la tua applicazione non usa, dlopen
non devi preoccupartene.
Un'altra opzione (e quella che preferisco) è quella di distribuire il più recente libstdc++.so
insieme alla tua applicazione e assicurarti che venga trovato prima del sistema predefinito libstdc++.so
, cosa che può essere eseguita forzando il linker dinamico a guardare nel posto giusto, utilizzando $LD_LIBRARY_PATH
la variabile di ambiente in run- time, o impostando un RPATH
nell'eseguibile al momento del collegamento. Preferisco usare RPATH
in quanto non si basa sull'ambiente impostato correttamente affinché l'applicazione funzioni. Se colleghi la tua applicazione con '-Wl,-rpath,$ORIGIN'
(nota le virgolette singole per evitare che la shell tenti di espandersi $ORIGIN
), l'eseguibile avrà una RPATH
delle $ORIGIN
quali dice al linker dinamico di cercare le librerie condivise nella stessa directory dell'eseguibile stesso. Se metti il file più recentelibstdc++.so
nella stessa directory dell'eseguibile verrà trovato in fase di esecuzione, problema risolto. (Un'altra opzione è inserire l'eseguibile /some/path/bin/
e la più recente libstdc ++. Così dentro /some/path/lib/
e collegarsi con '-Wl,-rpath,$ORIGIN/../lib'
o qualsiasi altra posizione fissa relativa all'eseguibile e impostare l'RPATH relativo a $ORIGIN
)
-static-libstdc++
opzione non avrebbe senso, useresti semplicemente-static