2010-05-18 14 views
81

Cuando compilo algo en mi Ubuntu Lucid 10.04 PC se vincula con glibc. Lucid usa 2.11 de glibc. Cuando ejecuto este binario en otra PC con un glibc anterior, el comando falla diciendo que no hay glibc 2.11 ...¿Cómo puedo enlazar a una versión específica de glibc?

Que yo sepa, glibc usa el control de versiones de símbolos. ¿Puedo forzar que gcc se vincule con una versión de símbolo específica?

En mi uso concreto, trato de compilar una cadena de herramientas gcc cross para ARM.

+44

Argh este es uno de esos problemas realmente molestos de Linux como que la solución siempre es "no deberías hacer eso", lo que por supuesto significa "no funciona y nadie lo ha arreglado todavía". – Timmmm

+0

La gente se quejaba del DLL hell en Windows. Recuerdo que * algunos * aficionados de Linux intentaron mencionarlo como un ejemplo particularmente horrible del mundo de Windows. Cuando me topé con * esto * haciendo desarrollo de Linux hace más de una década, todo lo que hice fue enterrar mi cara en mis manos. – 0xC0000022L

Respuesta

54

Tiene la razón porque glibc usa el control de versiones de los símbolos. Si tiene curiosidad, la implementación de versiones de símbolo introducida en glibc 2.1 se describe here y es una extensión del esquema de control de versiones de símbolos de Sun descrito here.

Una opción es vincular estáticamente su binario. Esta es probablemente la opción más fácil.

También puede crear su binario en un entorno de construcción chroot, o usando una nueva glibc- => glibc- edad compilador cruzado.

acuerdo con el puesto http://www.trevorpounds.com el blog Linking to Older Versioned Symbols (glibc), es posible forzar a cualquier símbolo se enlacen con una más antigua, siempre que es válido utilizando el mismo .symver pseudo-op que se utiliza para definir versionado símbolos en primer lugar. El siguiente ejemplo se extrajo del blog post.

El ejemplo siguiente hace uso de la ruta real de glibc, pero se asegura de que esté vinculado a una versión anterior de 2.2.5.

#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 no admite enlaces estáticos: los programas glibc vinculados estáticamente no funcionan en sistemas con diferentes versiones de libc. –

+2

'libc.a' de glibc sigue existiendo, glibc admite esto en * algunos * casos, aunque es [no recomendado (Drepper)] (http://www.akkadia.org/drepper/no_static_linking.html). Tendrá problemas con programas no triviales, especialmente cualquier cosa que use NSS (solución en [las preguntas frecuentes] (https://sourceware.org/glibc/wiki/FAQ)). –

15

Enlace con -static. Cuando se vincula con -static, el enlazador incrusta la biblioteca dentro del ejecutable, por lo que el ejecutable será más grande, pero se puede ejecutar en un sistema con una versión anterior de glibc porque el programa usará su propia biblioteca en lugar de la de el sistema.

+47

A menudo, la razón por la que desea hacer esto es porque está distribuyendo una aplicación de código cerrado. En este caso, a menudo no se permite vincular estáticamente por razones de licencia (para hacerlo, deberá liberar todo su código fuente), por lo que debe tener cuidado con -estático. – Malvineous

+1

Mientras tanto, al menos uno a menudo puede recurrir a musl-libc, pero con los programas en C++ las cosas pueden complicarse más, por lo que puede ser necesario especificar una versión de símbolo. – 0xC0000022L

Cuestiones relacionadas