Hay 2 argumentos para tener bibliotecas compartidas:
- Ayuda a reducir el espacio en disco.
- Cuando se actualiza una biblioteca compartida, todos los binarios que dependen de ella obtienen la actualización.
Hay principalmente un inconveniente para las bibliotecas compartidas:
- Ellos (pueden) introducir el infierno de dependencia.
En las computadoras de escritorio, la primera ventaja ya no es válida. La pérdida de espacio en disco no es un gran problema en estos días.
Tener archivos binarios estáticos nos permitiría ser mucho mejores administradores de paquetes; quiero decir, el infierno de la dependencia sería cosa del pasado. Agregar un programa sería simplemente agregar un binario; finalmente una carpeta para permitirle manejar sus archivos. Eliminar un programa sería simplemente eliminar este archivo. Dependencias? Ido.
La segunda ventaja sigue en pie, pero creo que la ventaja de los binarios estáticos en las computadoras de escritorio lo supera. Quiero decir, incluso los nuevos lenguajes como Go compilan todos sus binarios a pesar de las ventajas de las bibliotecas compartidas, debido a la conveniencia.
Dado que una de las principales ventajas de las bibliotecas compartidas ya no es un gran problema, ¿las bibliotecas estáticas en C todavía están mal vistas? Si es así, ¿por qué?
Respuestas:
La premisa de su pregunta es errónea. Lo que está mal visto es apegarse a doctrinarios y absolutos sin entender la base detrás de ellos (¿Programación de culto de carga?).
La respuesta SO vinculada es un estudio interesante en ese mismo tema: la pregunta era sobre por qué una compilación con la opción estática no funcionaba, la respuesta a la que se vinculó no fue más que una queja sobre no usar la vinculación estática. Si no discute por qué es malo, y exige que el OP utilice enlaces dinámicos. Es desafortunado que esté marcado como la respuesta correcta (la siguiente respuesta tiene el doble de votos y es la respuesta correcta a la pregunta del OP) porque aunque la respuesta correcta está allí, está profundamente oculta entre una opinión dogmática.
La verdadera pregunta es cuáles son los pros y los contras de los enlaces estáticos frente a los dinámicos y cuándo se preferiría uno sobre el otro.
fuente
Desde el punto de vista del desarrollador, la vinculación dinámica a menudo puede acelerar considerablemente su compilación / enlace / bucle de prueba.
Desde el punto de vista de la gestión de paquetes, tome libGL, por ejemplo. Tengo aproximadamente una docena de implementaciones diferentes disponibles en mi administrador de paquetes, algunas genéricas y otras específicas para tarjetas gráficas. Si no estuviera vinculado dinámicamente, tendría que haber una docena de versiones de cada programa que se vincule con libGL, o de lo contrario tendría que idear una capa adicional de abstracción que no sea tan eficiente como una llamada de función.
Piense en un problema de seguridad en una biblioteca popular como Qt. Con el enlace dinámico, puedo actualizar ese paquete, en lugar de tener que identificar, recompilar e implementar cada paquete que se vincule en Qt.
La vinculación estática puede tener ventajas en aplicaciones de código cerrado implementadas independientemente, pero en la gestión de paquetes de código abierto duele más de lo que ayuda.
fuente
Las bibliotecas compartidas son muy preferidas por los mantenedores de distribución de Linux básicamente por su razón # 2. Es realmente importante para ellos que, por ejemplo, cuando alguien encuentre un error de seguridad en zlib , no tengan que recompilar cada uno de los programas que usan zlib --- no solo les costaría más ciclos de CPU hacer el Al volver a compilar, todos los que usan la distribución tendrían que volver a descargar todos esos programas. Mientras tanto, dentro del conjunto de paquetes proporcionados por una distribución, el infierno de dependencia no es un problema, porque todo se prueba para que funcione con ese conjunto de bibliotecas.
Si está creando software de terceros que necesita bibliotecas que no están en su distribución, entonces vincular estáticamente esas bibliotecas puede ser menos complicado que la alternativa, y eso está bien.
La otra cosa importante que debe saber es que GNU
libc
y GCClibstdc++
tienen componentes que no funcionan de manera confiable si la biblioteca está estáticamente vinculada. El problema más común es condlopen
, porque cualquier módulo con el que carguedlopen
está vinculado dinámicamentelibc.so.6
. Eso significa que ahora tiene dos copias de la biblioteca C en su espacio de direcciones, y se produce hilaridad cuando no están de acuerdo sobre qué copia de lamalloc
estructura de datos interna (por ejemplo) es autorizada. Pero hay algo peor: un montón de funciones que no parece tener nada que ver condlopen
, al igual quegethostbyname
yiconv
, el usodlopen
internamente (para que su comportamiento sea configurable en tiempo de ejecución). Afortunadamente, el ABI para libc y libstdc ++ es muy estable, por lo que es poco probable que encuentre problemas para vincularlos dinámicamente.fuente
Estoy de acuerdo con el último punto de mattnz: esta pregunta es una pregunta cargada. Se supone que el enlace estático es malo. Puedo pensar en dos razones por las cuales este no es el caso:
La vinculación estática es segura: si una biblioteca compartida se actualiza de modo que una aplicación use la nueva (tal vez la nueva sobrescriba la anterior o se elimine la anterior), puede introducir el riesgo de que la nueva versión rompa la aplicación. Este es un cambio de código fuera del alcance de una actualización oficial de la aplicación. Puede que no haya sido probado. La vinculación estática evita esto al no compartir bibliotecas externamente. Sostengo que esto es una desventaja para las bibliotecas compartidas debido a este riesgo. ¿Qué sucede si una nueva versión de una biblioteca compartida presenta un nuevo error que rompe ciertas aplicaciones antiguas?
La vinculación estática garantiza que una aplicación sea más autónoma. Si bien las bibliotecas compartidas se pueden ubicar con el ejecutable principal, a menudo se depositan en ubicaciones compartidas. Las aplicaciones vinculadas estáticamente son más fáciles de garantizar "portátiles" en el sentido de que "no requieren cambios en los archivos, directorios o configuraciones propiedad del sistema operativo" (piense en el directorio, registro, / etc. de Windows).
fuente
Las bibliotecas estáticas y dinámicas tienen sus propios usos. Al observar una sola aplicación en su alcance, obtenemos una idea diferente sobre lo que es necesario y lo que no.
La vinculación estática simplifica drásticamente la implementación de aplicaciones. No tener que detectar y lidiar con diferentes versiones. Solo hornea y despliega.
La ventaja obvia con las bibliotecas dinámicas es la capacidad de aplicar actualizaciones de forma independiente.
Esta es una de las razones por las que odio a Maven y otros creadores de proyectos de vinculación dinámica similares para Java. Esperan que una única versión de la biblioteca esté disponible en una URL dada por siempre y para siempre. No entiendo el problema que ocurre en 10 años cuando nadie puede compilar la aplicación porque toda la fuente y los frascos se han ido.
fuente
FooLib1.8
solían incluir el código de esa biblioteca en su paquete ejecutable de una manera estándar, para permitir que una utilidad de actualización incluida loFooLib1.9
actualice o rebaje? La forma en que se almacenó el código en Classic Macintosh lo habría hecho bastante fácil; ¿Hay alguna razón por la cual los sistemas actuales no puedan hacerlo aún mejor?