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?