2012-10-09 22 views
5

Estoy leyendo el libro de O'Reilly 21st Century C en el que el autor afirma que al vincular con una biblioteca estática "el compilador [efectivamente] está copiando los contenidos relevantes de la biblioteca en el ejecutable final".¿Cómo se copia el código de objeto en ejecutable cuando se enlaza con la biblioteca estática?

me han tratado de probar esto mediante la creación de mi propia biblioteca estática que consiste en este módulo:

static char szStr[64]; 

char* single_func() { 
    strcpy(szStr, "Hello string!\r\n"); 
    return szStr; 
} 

void func0() { 
    strcpy(szStr, "Hello"); 
} 

char* func1() { 
    strcat(szStr, " string!\r\n"); 
    return szStr; 
} 

Para probar una creados para archivos de C, donde uno está llamando single_func() y la func0 otras llamadas() y func1().

Los ejecutables resultantes son 751290B en ambos casos. Si llamo strcpy y strcat directamente desde los módulos, ambos ejecutables terminan siendo 7215B.

¿Esto no está en conflicto con la declaración anterior o me falta algún detalle sobre la vinculación?

Una pregunta relacionada es que la biblioteca estática es 1600B, entonces ¿de dónde viene este aumento de tamaño?


adicional:

Ambos archivos principales consisten en nada más que llamar a las funciones y la impresión de los resultados, así:

main0:

#include <stdio.h> 
#include "sharedlib.h" 
int main() { 
    char* szStr = single_func(); 
    printf("%s", szStr); 
    return 0; 
} 

main1:

#include <stdio.h> 
#include "sharedlib.h" 
int main() { 
    char* szStr; 
    func0(); 
    szStr = func1(); 
    printf("%s", szStr); 
    return 0; 
} 

archivos fueron compilados como esto:

gcc -static main0.c -L. -lsharedlib -o main0 

plataforma es Linux y el compilador gcc es v4.6.3.

Respuesta

3

Con bibliotecas estáticas, la unidad de copia es el archivo objeto de la biblioteca. Como ambos programas llaman a una función desde el archivo objeto, ambos programas terminan con todo el archivo objeto en el ejecutable, por lo tanto, el mismo resultado de tamaño (dar o tomar el tamaño del programa main() que realiza la llamada).

La información adicional en el archivo ejecutable podría provenir de varios lugares. Parte de esto será información de control y depuración. Parte de esto podría ser de la biblioteca C si también lo vinculaste estáticamente. Probablemente necesitemos ver el programa principal y las líneas de enlace, y conocer la plataforma para encontrar otras razones para la inflación.

+1

He actualizado mi pregunta con la información adicional que solicitó pero creo que puedo comenzar a ver a dónde va esto. 1: cuando se usa una sola función del archivo de objeto de una biblioteca, todo el archivo objeto se transfiere al ejecutable. 2: al usar la opción -static, todas las bibliotecas se transfieren al ejecutable final, produciendo el tamaño de archivo más grande. ¿Estoy en lo correcto en esto? – Kenneth

+1

Sí; tienes razón en ambos detalles. Si mira el libro de Plauger 'The Standard C Library' (para el estándar C89), verá que la mayoría de los archivos fuente tienen una función externamente visible para que no arrastre lo que no usa al ejecutable. Probablemente puedas reducir drásticamente el tamaño de tu ejecutable añadiendo '-shared' a la línea de comando después de' -lsharedlib'. –

+0

Estoy un poco sorprendido de que la biblioteca C esté (parece estar) vinculada de forma estática. En un momento (hace una década, tal vez) pensé que la biblioteca C no se suministraba como una biblioteca estática (por lo que tenía que ser compartida).Es posible que esté perdiendo el recuerdo, o puede haber sido en una variante de Unix en lugar de Linux. Puede verificar lo que se está cargando como una biblioteca compartida con 'ldd main0'. Enumerará los objetos compartidos usados. –

Cuestiones relacionadas