Por que não __attribute __ (() construtor) trabalham em uma biblioteca estática?
-
05-07-2019 - |
Pergunta
No exemplo a seguir, o programa deve imprimir "foo chamado":
// foo.c
#include <stdio.h>
__attribute__((constructor)) void foo()
{
printf("foo called\n");
}
// main.c
int main()
{
return 0;
}
Se o programa é compilado como este, ele funciona:
gcc -o test main.c foo.c
No entanto, se foo.c é compilado em uma biblioteca estática, o programa imprime nada.
gcc -c main.c
gcc -c foo.c
as rcs foo.a foo.o
gcc -o test foo.a main.o
Por que isso acontece?
Solução
O vinculador não incluir o código em foo.a no programa final, porque nada em referências main.o TI. Se main.c
é reescrito da seguinte forma, o programa funcionará:
//main.c
void foo();
int main()
{
void (*f)() = foo;
return 0;
}
Além disso, quando compilando com uma biblioteca estática, a ordem dos argumentos para gcc (ou o ligador) é significativo: a biblioteca deve vir após os objetos que referência it
.gcc -o test main.o foo.a
Outras dicas
Como foi afirmado, símbolos sem referência de arquivo não torná-lo para o binário de saída, porque devoluções vinculador-los por padrão.
Para substituir esse comportamento quando ligar com a biblioteca estática, pode ser utilizado opções --whole-archive
/ --no-whole-archive
para o vinculador, 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
Isso pode levar a binário inchado, porque todos os símbolos de foo.a
será incluído pelo vinculador para a saída, mas às vezes é justificada.