2012-05-30 3 views
33

Devo compilare un programma su un ubuntu corrente (12.04). Questo programma dovrebbe quindi essere eseguito su un cluster utilizzando CentOS con un kernel precedente (2.6.18). Purtroppo non posso compilare direttamente sul cluster. Se compilo e copio il programma senza modifiche, ricevo il messaggio di errore "kernel troppo vecchio".Compilare con libc meno recenti (versione `GLIBC_2.14 'non trovata)

Il modo in cui l'ho capito, la ragione di ciò non è tanto la versione del kernel, ma la versione di libc che è stata utilizzata per la compilazione. Così ho provato a compilare il mio programma collegando dinamicamente la libc dal cluster e collegando staticamente tutto il resto.

Research

ci sono già un sacco di domande su questo su SO, ma nessuna delle risposte davvero lavorato per me. Così qui è la mia ricerca su questo argomento:

  • This question spiega il motivo per il kernel troppo vecchio messaggio
  • This question è simile ma più specializzata e non ha risposte
  • linkare staticamente come proposto here non ha funzionato perché la libc è troppo vecchia sul cluster. Una risposta menziona anche di costruire usando la vecchia libc, ma non spiega come farlo.
  • One way si compila in una macchina virtuale che esegue un sistema operativo precedente. Questo ha funzionato, ma è complicato. Ho anche letto che you should not link libc statically
  • Apparently si is possible per compilare per una versione libc diverso con l'opzione -rpath ma questo non ha funzionato per me (vedi sotto)

stato attuale

Ho copiato il in seguito i file dal cluster nella directory /path/to/copied/libs

  • libc-2.5.so
  • libgcc_s.so.1
  • libstdC++. So.6

e sto compilazione con le opzioni -nodefaultlibs -Xlinker -rpath=/path/to/copied/libs -Wl,-Bstatic,-lrt,-lboost_system,-lboost_filesystem -Wl,-Bdynamic,-lc,-lstdc++,-lgcc_s

L'uscita del ldd sul binario compilato è

mybin: /path/to/copied/libs/libc.so.6: version `GLIBC_2.14' not found (required by mybin) 
mybin: /path/to/copied/libs/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by mybin) 
linux-vdso.so.1 => (0x00007ffff36bb000) 
libc.so.6 => /path/to/copied/libs/libc.so.6 (0x00007fbe3789a000) 
libstdc++.so.6 => /path/to/copied/libs/libstdc++.so.6 (0x00007fbe37599000) 
libgcc_s.so.1 => /path/to/copied/libs/libgcc_s.so.1 (0x00007fbe3738b000) 
/lib64/ld-linux-x86-64.so.2 (0x00007fbe37bf3000) 
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fbe37071000) 

I' m un po 'confuso dall'errore, perché usa il percorso corretto (es la libc dal cluster) ma si lamenta ancora di una versione glibc mancante. Quando si esegue ldd sul cluster, restituisce not a dynamic executable ed esegue i risultati binari negli stessi due errori menzionati sopra. Sembra anche che siano incluse altre librerie (linux-vdso.so.1, ld-linux-x86-64.so.2 e libm.so.6). Devo usare anche le versioni precedenti per quelle?

Così ora ho due domande principali:

  • È questo anche il corretto approccio qui?
  • In caso affermativo: come collego correttamente la vecchia libc?

risposta

10

Vedere la risposta this.

È questo anche il corretto approccio qui

No: non è possibile utilizzare non corrispondenti versioni di glibc come il vostro comando di collegamento fa. Hai utilizzato crt0.o e ld-linux.so da nuovo (installato dal sistema) libc, ma libc.so.6 da una vecchia (copia dal cluster) libc. Questo non funzionerà.

2

-rpath imposta il tag DT_RPATH ma non dice il linker a cercare lì per librerie, si vuole -L per questo.