Pregunta

En el siguiente ejemplo, el programa debería imprimir " foo llamado " ;:

// foo.c
#include <stdio.h>

__attribute__((constructor)) void foo()
{
    printf("foo called\n");
}

// main.c
int main()
{
    return 0;
}

Si el programa se compila así, funciona:

gcc -o test main.c foo.c

Sin embargo, si foo.c se compila en una biblioteca estática, el programa no imprime nada.

gcc -c main.c
gcc -c foo.c
as rcs foo.a foo.o
gcc -o test foo.a main.o

¿Por qué sucede esto?

¿Fue útil?

Solución

El enlazador no incluye el código en foo.a en el programa final porque nada en main.o lo referencia. Si main.c se reescribe de la siguiente manera, el programa funcionará:

//main.c

void foo();

int main()
{
    void (*f)() = foo;
    return 0;
}

Además, al compilar con una biblioteca estática, el orden de los argumentos para gcc (o el vinculador) es significativo: la biblioteca debe ir después de los objetos que la referencian.

gcc -o test main.o foo.a

Otros consejos

Como se indicó, los símbolos no referenciados del archivo no llegan al binario de salida, porque el vinculador los descarta de forma predeterminada.

Para anular este comportamiento cuando se vincula con una biblioteca estática, se pueden usar las opciones --whole-archive / --no-whole-archive para el enlazador, como este :

gcc -c main.c
gcc -c foo.c
ar rcs foo.a foo.o
gcc -o test -Wl,--whole-archive foo.a -Wl,--no-whole-archive main.o

Esto puede llevar a un binario inflado, porque el vinculador incluirá todos los símbolos de foo.a en la salida, pero a veces está justificado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top