Perché __attribute __ ((costruttore)) non funziona in una libreria statica?
-
05-07-2019 - |
Domanda
Nel seguente esempio, il programma dovrebbe stampare " pippo chiamato " ;:
// foo.c
#include <stdio.h>
__attribute__((constructor)) void foo()
{
printf("foo called\n");
}
// main.c
int main()
{
return 0;
}
Se il programma è compilato in questo modo, funziona:
gcc -o test main.c foo.c
Tuttavia, se foo.c è compilato in una libreria statica, il programma non stampa nulla.
gcc -c main.c
gcc -c foo.c
as rcs foo.a foo.o
gcc -o test foo.a main.o
Perché succede?
Soluzione
Il linker non include il codice in foo.a nel programma finale perché nulla in main.o lo fa riferimento. Se main.c
viene riscritto come segue, il programma funzionerà:
//main.c
void foo();
int main()
{
void (*f)() = foo;
return 0;
}
Inoltre, quando si compila con una libreria statica, l'ordine degli argomenti su gcc (o sul linker) è significativo: la libreria deve venire dopo gli oggetti che la fanno riferimento.
gcc -o test main.o foo.a
Altri suggerimenti
Come è stato affermato, i simboli non referenziati dall'archivio non arrivano al file binario di output, perché il linker li scarta per impostazione predefinita.
Per sovrascrivere questo comportamento durante il collegamento con la libreria statica, è possibile utilizzare le opzioni --whole-archive
/ --no-whole-archive
per il linker, in questo modo :
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
Questo può portare a un binario gonfio, perché tutti i simboli da foo.a
saranno inclusi dal linker all'output, ma a volte è giustificato.