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?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top