2012-05-30 24 views
33

Tengo que compilar un programa en un ubuntu actual (12.04). Este programa debería ejecutarse en un clúster usando CentOS con un Kernel anterior (2.6.18). No puedo compilar en el clúster directamente, desafortunadamente. Si solo compilo y copio el programa sin ningún cambio, aparece el mensaje de error "kernel too old".Compilar con libc anterior (no se encuentra la versión `GLIBC_2.14 ')

De la manera que lo entendí, la razón para esto no es tanto la versión de Kernel, sino la versión de libc que se usó para la compilación. Así que traté de compilar mi programa vinculando dinámicamente la libc del clúster y vinculando estáticamente todo lo demás.

Investigación

Ya hay un montón de preguntas acerca de esto en SO pero ninguna de las respuestas realmente trabajó para mí. Así que aquí está mi investigación sobre ese tema:

  • This question explica la razón del Kernel mensaje demasiado viejo
  • This question es similar pero más especializado y no tiene respuestas
  • enlazado estático como se propone here no funcionó porque la libc es demasiado antigua en el clúster. Una respuesta también menciona construir usando el viejo libc, pero no explica cómo hacerlo.
  • One way es compilar en una máquina virtual que ejecuta un sistema operativo anterior. Esto funcionó pero es complicado. También leí que you should not link libc statically
  • Apparently que is possible para compilar una versión de libc diferente con la opción -rpath pero esto no funcionó para mí (ver más abajo)

estado actual

Copié el siguientes archivos del clúster en el directorio /path/to/copied/libs

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

y estoy compilando con las opciones -nodefaultlibs -Xlinker -rpath=/path/to/copied/libs -Wl,-Bstatic,-lrt,-lboost_system,-lboost_filesystem -Wl,-Bdynamic,-lc,-lstdc++,-lgcc_s

La salida de ldd en el binario compilado es

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 algo confundido por el error, porque usa la ruta correcta (es decir, la libc del clúster) pero aún se queja de una versión faltante de glibc. Al ejecutar ldd en el clúster, devuelve not a dynamic executable y ejecuta los resultados binarios en los mismos dos errores mencionados anteriormente. También parece que hay otras bibliotecas incluidas (linux-vdso.so.1, ld-linux-x86-64.so.2 y libm.so.6). ¿Debo usar las versiones anteriores para esos también?

Así que ahora tengo dos preguntas principales:

  • ¿Es esto el enfoque correcto aquí?
  • En caso afirmativo, ¿cómo puedo vincular la biblioteca antigua correctamente?

Respuesta

10

Ver this answer.

¿Es esto el enfoque correcto aquí

No: no se puede utilizar que no coinciden las versiones de glibc como su comando de enlace hace. Usó crt0.o y ld-linux.so de nueva (instaladas en el sistema) libc, pero libc.so.6 de una libc antigua (copiada del clúster). Eso no va a funcionar.

2

-rpath establece la etiqueta DT_RPATH pero no le dice al enlazador para buscar allí en las librerías, desea -L para eso.

Cuestiones relacionadas