while serie linking library error compile gcc linker shared-libraries

gcc - serie - Compilar con libc anterior(no se encuentra la versión `GLIBC_2.14 '')



error while loading shared libraries linux (2)

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".

Tal como lo entendí, la razón para esto no es tanto la versión de Kernel, sino la versión de libc que se utilizó 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 muchas preguntas sobre esto en SO, pero ninguna de las respuestas realmente funcionó para mí. Así que aquí está mi investigación sobre ese tema:

  • Esta pregunta explica la razón del mensaje Kernel demasiado viejo
  • Esta pregunta es similar pero más especializada y no tiene respuestas
  • La vinculación estática 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.
  • Una forma es compilar en una máquina virtual que ejecuta un sistema operativo antiguo. Esto funcionó pero es complicado. También leí que no deberías vincular libc estáticamente
  • Apparently es posible compilar para una versión de libc diferente con la opción -rpath pero esto no funcionó para mí (ver abajo)

Estado actual

Copié los 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)

Estoy 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, no 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?

Entonces ahora tengo dos preguntas principales:

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

Vea this respuesta.

¿Es este el enfoque correcto aquí?

No: no puede usar versiones desajustadas de glibc como lo hace su comando de enlace. Usó crt0.o y ld-linux.so de la nueva libc (instalada en el sistema), pero libc.so.6 de una libc antigua (copiada del clúster). Eso no va a funcionar.


-rpath establece la etiqueta DT_RPATH pero no le dice al vinculador que busque allí libs, usted quiere -L para eso.