2010-05-18 11 views
81

Quando compilo qualcosa sul mio Ubuntu Lucid 10.04 PC viene collegato a glibc. Lucid usa 2.11 di glibc. Quando eseguo questo binario su un altro PC con un vecchio glibc, il comando non riesce a dire che non c'è glibc 2.11 ...Come posso collegarmi ad una specifica versione di glibc?

Per quanto ne so, glibc utilizza il controllo delle versioni dei simboli. Posso forzare gcc al collegamento con una versione di simbolo specifica?

Nel mio uso concreto, provo a compilare una catena di strumenti gcc cross per ARM.

+44

Argh questo è uno di quei fastidiosi problemi di linux come dove la soluzione è sempre "non dovresti farlo", che ovviamente significa "non funziona e nessuno l'ha ancora risolto". – Timmmm

+0

Le persone si sono lamentate dell'inferno DLL su Windows. Ricordo che Linux * alcuni * appassionati cercavano di farlo apparire come un esempio particolarmente orribile dal mondo Windows. Quando mi sono imbattuto per la prima volta in * questo * sviluppo di Linux oltre un decennio fa, tutto quello che ho fatto è stato seppellire la mia faccia tra le mie mani. – 0xC0000022L

risposta

54

Si è corretto in che glibc utilizza il controllo delle versioni dei simboli. Se sei curioso, l'implementazione del versioning dei simboli introdotta in glibc 2.1 è descritta nello here ed è un'estensione dello schema di versioning dei simboli di Sun descritto here.

Un'opzione consiste nel collegamento statico del file binario. Questa è probabilmente l'opzione più semplice.

Si potrebbe anche costruire il vostro binario in un ambiente di generazione chroot, o utilizzando un glibc- nuova => glibc- vecchia cross-compilatore.

Secondo il post http://www.trevorpounds.com blog Linking to Older Versioned Symbols (glibc), è possibile forzare qualsiasi simbolo per essere collegato contro una più vecchia finché è valido utilizzando il medesimo .symver pseudo-op che viene utilizzato per definire con versione simboli in primo luogo. Il seguente esempio è tratto da blog post.

L'esempio seguente utilizza il percorso reale di glibc, ma si assicura che sia collegato a una versione 2.2.5 precedente.

#include <limits.h> 
#include <stdlib.h> 
#include <stdio.h> 

__asm__(".symver realpath,[email protected]_2.2.5"); 
int main() 
{ 
    char* unresolved = "/lib64"; 
    char resolved[PATH_MAX+1]; 

    if(!realpath(unresolved, resolved)) 
     { return 1; } 

    printf("%s\n", resolved); 

    return 0; 
} 
+10

glibc non supporta il collegamento statico: i programmi glibc collegati in modo statico non funzionano su sistemi con versioni di libc differenti. –

+2

'libc.a' di glibc continua ad esistere, glibc lo supporta in * alcuni * casi, sebbene sia [non raccomandato (Drepper)] (http://www.akkadia.org/drepper/no_static_linking.html). Avrai problemi con i programmi non banali, specialmente con quelli che utilizzano NSS (soluzione in [le FAQ] (https://sourceware.org/glibc/wiki/FAQ)). –

15

Collegamento con -static. Quando si collega con -static il linker incorpora la libreria all'interno dell'eseguibile, quindi l'eseguibile sarà più grande, ma può essere eseguito su un sistema con una versione precedente di glibc perché il programma utilizzerà la propria libreria anziché quella di il sistema.

+47

Spesso il motivo per cui vuoi farlo è perché stai distribuendo un'applicazione closed-source. In questo caso, spesso non è consentito il collegamento statico per motivi di licenza (per farlo dovresti rilasciare tutto il tuo codice sorgente), quindi devi stare attento con -statico. – Malvineous

+1

Nel frattempo almeno uno può ricorrere a musl-libc, ma con i programmi C++ le cose possono diventare più complicate, quindi è ancora necessario specificare una versione di un simbolo. – 0xC0000022L