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?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top