2012-04-22 11 views
7

Con respecto al siguiente enlace: http://www.archlinux.org/news/libpnglibtiff-rebuilds-move-from-testing/¿Por qué debería recompilar un programa completo solo para una actualización de la biblioteca?

Podría alguien explicarme por qué un programa debe ser reconstruido después de una de sus bibliotecas se ha actualizado?

¿Cómo es que tiene sentido ya que el archivo "principal" no se cambia en absoluto?

+0

Muy similar a http://stackoverflow.com/a/10269818/841108 –

Respuesta

13

Si las firmas de las funciones involucradas no han cambiado, entonces "reconstruir" el programa significa que los archivos del objeto deben ser vinculados nuevamente. No debería necesitar compilar ellos de nuevo.

Una API es un contrato que describe la interfaz a las funciones públicas en una biblioteca. Cuando el compilador genera código, necesita saber qué tipo de variables pasar a cada función y en qué orden. También necesita saber el tipo de devolución, por lo que conoce el tamaño y el formato de los datos que se devolverán desde la función. Cuando se compila el código, la dirección de una función de biblioteca puede representarse como "inicio de la biblioteca, más 140 bytes". El compilador no conoce la dirección absoluta, por lo que simplemente especifica un desplazamiento desde el principio de la biblioteca.

Pero dentro de la biblioteca, los contenidos (es decir, las implementaciones de las funciones) pueden cambiar. Cuando eso sucede, la longitud del código puede cambiar, por lo que las direcciones de las funciones pueden cambiar. El trabajo del vinculador es comprender dónde residen los puntos de entrada de cada función y completar esas direcciones en el código objeto para crear el ejecutable.

Por otro lado, si los estructuras de datos en la biblioteca han cambiado y la biblioteca requiere las personas que llaman a gestionar la memoria (una mala práctica, pero, por desgracia común), entonces se necesidad de volver a compilar el código para puede dar cuenta de los cambios. Por ejemplo, si su código usa malloc(sizeof(dataStructure)) para asignar memoria a una estructura de datos de biblioteca que se ha duplicado, debe volver a compilar su código porque sizeof(dataStructure) tendrá un valor mayor.

+0

En otras palabras, usted dice que volver a vincular es esencial solo cuando se actualizan las funciones de una biblioteca. Sin embargo, en la práctica no reconstruimos eso a menudo a pesar de las actualizaciones constantes de la biblioteca. ¿Cómo es eso? – kstratis

+1

¿La biblioteca está vinculada estática o dinámicamente? ? Las bibliotecas dinámicas se cargan en tiempo de ejecución, mientras que las bibliotecas estáticas se vinculan al ejecutable a medida que se construye. –

+0

Eliminé mi comentario anterior y estoy volviendo a escribir mi pregunta: Con respecto a lo que dice en el 3er párrafo sobre las direcciones de función: Supongamos que tenemos una biblioteca con 2 funciones; y . Ahora todo está compilado y funcionando bien. De acuerdo con su sugerencia, si coloco una declaración de impresión sencilla dentro del primer método, ¿debo volver a vincular mi programa a la biblioteca debido a la nueva longitud del código? De lo contrario, explique en qué caso la reconstrucción sería apropiada. – kstratis

5

Hay dos tipos de compatibilidad: API y ABI.

compatibilidad API es acerca de las funciones y estructuras de datos que otros programas pueden confiar. Por ejemplo, si la versión 0.1 de libfoo define una función API llamada "hello_world()", y la versión 0.2 la elimina, cualquier programa que dependa de "hello_world()" necesita actualizarse para funcionar con la nueva versión de libfoo.

compatibilidad ABI se trata de los supuestos de cómo funciones y, en particular, estructuras de datos están representados en los binarios. Si, por ejemplo libfoo 0.1 también se define una estructura de datos recipe con dos campos: "instrucciones" y "ingredientes" y libfoo 0,2 Presenta "mediciones" antes del campo "ingredientes", entonces los programas basados ​​en libfoo 0.1 recetas deben compilarse porque las "instrucciones" y los campos de "ingredientes" probablemente estarán en diferentes posiciones en la versión 0.2 del binario libfoo.so.

+0

¿Podría darnos un ejemplo de que después de una actualización no necesitaría reconstruir 'mi programa'? – kstratis

+0

Supongamos que tiene un código que calcula un valor de la secuencia de fibonacci a través de una función 'int fib (int index)'. Supongamos que en libfoo 0.1 la función resuelve este problema recursivamente (es decir: 'fib (n) = fib (n-1) + fib (n-2)') y en libfoo 0.2 los autores se dieron cuenta de que hay una solución cerrada y la aplicaron para un aumento de velocidad importante y reducción de uso de memoria. El comportamiento de la función es "funcionalmente" idéntico. La firma y la ubicación de la función siguen siendo las mismas. Entonces no hay necesidad de recompilación. – user268396

+0

Estoy confundido aquí ... ¡Adam Liss sugiere lo contrario! Por favor, lea mi comentario debajo de su publicación. – kstratis

0

¿Qué es "biblioteca"?

si una "biblioteca" es solamente un binario (por ejemplo, una biblioteca enlazada dinámicamente también conocido como ".dll", ".dylib" o ".so '; o una biblioteca enlazado estáticamente aka' .lib" o".a "), entonces no hay necesidad de recompilar, el volver a vincular debería ser suficiente (e incluso eso se puede evitar en algunos casos especiales)

otoh, las bibliotecas a menudo consisten en algo más que el objeto binario, por ejemplo, el encabezado los archivos pueden incluir alguna lógica en línea (o macro) si es así, volver a vincular no es suficiente, y es posible que tenga que volver a compilar para utilizar la versión más reciente de la lib.

+0

¿Qué pasa con las bibliotecas vinculadas estáticamente? –

+0

@ adam-liss: bueno, con las bibliotecas vinculadas estáticamente, su binario es autónomo (con respecto a la biblioteca), así que si no le importan las correcciones de errores/... en la nueva versión de la biblioteca no lo hace Tengo que volver a compilar/volver a vincular. si desea que cualquier característica/corrección nueva de la biblioteca tenga un efecto en su aplicación, se aplica el mismo principio: si cambia lo que se ve en los archivos de encabezado (la API pública + alguna macro/pegamento en línea), debe recompilar; si solo cambia la implementación de la biblioteca, es suficiente volver a vincular –

Cuestiones relacionadas