2009-05-01 7 views
36

Necesito distribuir un archivo binario que se ejecutará en la mayor cantidad posible de distribuciones Linux x86. Eso significa que tengo que vincular estáticamente algunas bibliotecas, como glibc, porque el usuario puede no tener la versión que uso. Se deben vincular dinámicamente otras bibliotecas, como fontconfig, porque se basa en un formato de archivo de caché y ubicaciones codificadas que pueden diferir en cada sistema.Utilice bibliotecas estáticas y vinculadas dinámicamente en gcc

¿Cuáles son las opciones de línea de comando para hacer esto? Si especifico -static, entonces gcc se negará a enlazar dinámicamente ninguna biblioteca.

Respuesta

68

enlazado dinámico con cualquier biblioteca del sistema, y ​​especialmente contra libc, en modernos sistemas UNIX o Linux hace que el binario significativamente menos portátil. Simplemente no lo hagas.

En su lugar, use compatibilidad con versiones anteriores (los binarios enlazados en un sistema anterior continúan ejecutándose en todos los más nuevos) para su ventaja, ya sea vinculando su binario en un sistema antiguo (uso RedHat 6.2, y no he visto un Linux sistema donde mi binario no se ejecutará en los últimos 8 años), o usando algo como autopackage.

Para responder a su pregunta original:

gcc main.o -Wl,-Bstatic -lfoo -Wl,-Bdynamic 

hará que enlazador a utilizar la versión del archivo libtal. [Es importante tener el -Wl,-Bdynamic final precisamente para no forzar la libc estática.]

+6

primera vez que he visto una explicación para esa dinámica final, aclamaciones –

2

Intente pasar las rutas de acceso a los archivos de la biblioteca a los que está vinculando en la línea de comando del vinculador (ya sean bibliotecas .a o .so) y drop -static. Eso debería hacer el truco.

+0

Cuando no hay '-estático' también hay la opción' -l: 'de ld, que se puede usar para vincular algunas bibliotecas por nombre completo, sin expandirlo a' lib + name + .so': ' -l: libsome_library.a' (https://sourceware.org/binutils/docs-2.18/ld/Options.html - '-lnamespec'" Si namespec es de la forma: nombre de archivo, ld buscará en la ruta de la biblioteca un archivo llamado nombre de archivo, otherise buscará en la ruta de la biblioteca un archivo llamado libnamespec.a. ") – osgx

3

Se debe tener en cuenta que, en Linux, solo se puede (estáticamente) vincular estáticamente una biblioteca si ninguna de las bibliotecas dinámicas depende en eso. Esto significa que si está utilizando alguna biblioteca dinámica, puede olvidarse de vincular estáticamente libc. Solo use una versión bastante antigua para compilar contra el caso de libc; libc ha mantenido una fuerte compatibilidad ABI hacia atrás a lo largo de los años.

Cuestiones relacionadas