static libraries - Tamaño de una biblioteca y el ejecutable
static-libraries static-linking (7)
@Todo: gracias por los consejos. @Greg Hewgill - Tu respuesta fue un buen indicador. Gracias.
La respuesta que descubrí fue la siguiente:
1.) Durante la construcción de la Biblioteca, lo que ocurre es que si la opción "Mantener depuración del programa databse" en MSVC (o algo similar) está activada, entonces la biblioteca tendrá esta información de depuración aumentando su tamaño. pero cuando incluyo estáticamente esa biblioteca y creo un ejecutable, el vinculador elimina toda la información de depuración de la biblioteca antes de generar el exe y, por lo tanto, el tamaño del exe es menor que el de la biblioteca.
2.) Cuando deshabilité la opción "Mantener búfer de datos de depuración del programa", obtuve una biblioteca cuyo tamaño era más pequeño que el ejecutable final, que era lo que pensaba que era nromal en la mayoría de las situaciones.
-ANUNCIO
Tengo una biblioteca estática * .lib creada usando MSVC en Windows. El tamaño de la biblioteca es, por ejemplo, 70 KB. Entonces tengo una aplicación que vincula esta biblioteca. Pero ahora el tamaño del ejecutable final (* .exe) es de 29 KB, menos que la biblioteca. Lo que quiero saber es:
Dado que la biblioteca está vinculada de forma estática, estaba pensando que debería agregarse directamente al tamaño del archivo ejecutable y que el tamaño del archivo ejecutable final debería ser más que eso. ¿El formato de Windows exe también hace algo de compresión de los datos binarios?
¿Cómo es para los sistemas Linux, así es como se relacionan los tamaños de la biblioteca en Linux (* .a / *. La la) con el tamaño del ejecutable de Linux (* .out)?
-ANUNCIO
La biblioteca estática probablemente contiene varias funciones que nunca se usan. Cuando el enlazador vincula la biblioteca con el ejecutable principal, ve que ciertas funciones nunca se utilizan (y que sus direcciones nunca se toman y almacenan en indicadores de función), simplemente descarta el código. También puede hacerlo de forma recursiva: si nunca se llama a la función A (), y A () llama a B (), pero nunca se llama a B (), puede eliminar el código para A () y B (). En Linux, sucede lo mismo.
Una biblioteca estática debe contener todos los símbolos definidos en su código fuente, ya que puede vincularse a un ejecutable que solo necesita ese símbolo específico. Pero una vez que está vinculado a un ejecutable, sabemos exactamente qué símbolos terminan siendo utilizados y cuáles no. Por lo tanto, el vinculador puede eliminar trivialmente el código no utilizado, recortando mucho el tamaño del archivo. Del mismo modo, cualquier símbolo duplicado (todo lo que está definido tanto en la biblioteca estática como en el ejecutable al que está vinculado se fusiona en una única instancia).
Una biblioteca estática tanto en Windows como en Unix es una colección de archivos .obj / .o. El vinculador examina cada uno de estos archivos de objeto y determina si es necesario que el programa se vincule. Si no es necesario, el archivo del objeto no se incluirá en el ejecutable final. Esto puede conducir a archivos ejecutables que son más pequeños que la biblioteca.
EDITAR: Como señala MSalters, en Windows, el compilador de VC ++ ahora admite la generación de archivos de objetos que permiten la vinculación a nivel de funciones, por ejemplo, ver aquí . De hecho, edit-and-continue requiere esto, ya que el edit-and-continue necesita poder reemplazar la parte más pequeña posible del ejecutable.
Descargo de responsabilidad : Ha pasado mucho tiempo desde que lidié con enlaces estáticos, así que tome mi respuesta con un grano de sal.
Usted escribió: ¿Estaba pensando que debería agregar directamente al tamaño del ejecutable y el tamaño del exe final debería ser más que eso?
Los enlazadores ingenuos funcionan exactamente de esta manera: hace mucho tiempo, cuando estaba desarrollando Hobby para sistemas CP / M (hace mucho tiempo), este era un problema real.
Sin embargo, los enlazadores modernos son más inteligentes: solo vinculan las funciones a las que hace referencia el código original o según se requiera.
Además de las respuestas actuales, el vinculador puede eliminar las definiciones de funciones si tienen un código de objeto idéntico, con la intención de ayudar a reducir los efectos de distensión del código de plantilla.
Hay información de contabilidad adicional en el archivo .lib
que no es necesaria para el ejecutable final. Esta información ayuda al vinculador a encontrar el código para vincularlo realmente. Además, la información de depuración se puede almacenar en el archivo .lib
pero no en el archivo .exe
(no recuerdo dónde se almacena la información de depuración para objs en un archivo lib, sino en otra parte).