2008-12-16 21 views
9

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 yo quiero saber es:Tamaño de una biblioteca y el ejecutable

  1. Desde la biblioteca se vincula estáticamente, estaba pensando que debería añadir directamente al tamaño del ejecutable y el tamaño final exe debe ser más que eso? ¿El formato de Windows exe también hace algo de compresión de los datos binarios?

  2. ¿Cómo se relaciona el tamaño de la biblioteca en Linux (* .a/*. La la) con el tamaño del ejecutable de Linux (* .out)?

-AD

Respuesta

5

Hay información adicional de contabilidad 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 otro lugar).

4

La biblioteca estática probablemente contiene varias funciones que no se utilizan. 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.

+0

En realidad no es sólo las funciones de referencia, sino que, además de los símbolos en los mismos archivos * .o (es decir, objetos enteros son lanzados en el resultado final, no sólo funciones), por lo que si A y B están en el mismo .o que C, y se llama a C, entonces todos estarán allí. – tgamblin

+1

No necesariamente, solo con compiladores/enlazadores tontos. – MSalters

+0

¿Puedo suponer que el enlazador GNU que está en la cadena de herramientas de GCC es uno de los más inteligentes? (Usted dijo "En Linux", que implica fuertemente la cadena de herramientas GCC.) – steveha

11

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, consulte here. 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.

+0

La vinculación a nivel de archivos es realmente un problema de UNIX; para MSVC la norma se ha convertido en enlace a nivel de función. – MSalters

0

Descargo de responsabilidad: Ha pasado mucho tiempo desde que manejé la vinculación estática, 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 archivo ejecutable final debería ser más que eso?

Los enlazadores ingenuos funcionan exactamente de esta manera: hace mucho tiempo, cuando estaba desarrollando hobbies para sistemas CP/M (hace mucho tiempo), esto era un problema real.

Los enlazadores modernos son más inteligentes, sin embargo, solo enlazan en las funciones a las que hace referencia el código original o según se requiera.

+0

No son solo las funciones a las que se hace referencia, sino que además de cualquier símbolo en los mismos archivos * .o (es decir, el archivo .o es la granularidad de los enlaces). – tgamblin

+0

Tienes razón, un detalle que había olvidado mientras tanto. ¡Es casi como la arqueología de software! – Bevan

0

Además de las respuestas actuales, el vinculador puede eliminar las definiciones de funciones si tienen un código de objeto idéntico, esto es para ayudar a reducir los efectos de distensión del código de plantilla.

+0

No creo que sea del todo cierto: ¿Estás pensando en C++, supongo? La eliminación de duplicados debe basarse en la FIRMA de la función (por ejemplo, el nombre y los tipos de argumentos) más que en el código del objeto. Si tiene dos funciones con código diferente pero con la misma firma, ¿qué ocurre ...? – Roddy

+0

No, en realidad estoy pensando en el código objeto. El enlazador puede eliminar una función si el código objeto generado es idéntico al de otro. Puede ver esto en un depurador, por ejemplo, puede ver trazas de pila para código optimizado que tiene funciones diferentes a las que cabría esperar en él –

0

Una biblioteca estática tiene que contener todos los símbolo definido en su código fuente, ya que podría se enlaza en un archivo ejecutable que necesita precisamente eso 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 sola instancia.

0

@Todo: Gracias por los indicadores @Greg Hewgill: Su respuesta fue un buen puntero .. Gracias

la respuesta que descubrí fue el siguiente:

1.) Durante edificio de la biblioteca es lo que ocurre si la opción "Mantener Programa de depuración dATABSE" en MSVC (o algo parecido) está en ON, entonces la biblioteca tendrá esta información de depuración hinchando 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 depuración del programa databse", obtuve una biblioteca cuyo tamaño era más pequeño que el ejecutable final, que era lo que pensé que era nromal en la mayoría de las situaciones.

-AD

Cuestiones relacionadas