Frage

Im folgende Beispiel soll das Programm drucken „foo genannt“:

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

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

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

Wenn das Programm wie folgt kompiliert wird, funktioniert es:

gcc -o test main.c foo.c

Wenn jedoch foo.c in eine statische Bibliothek kompiliert wird, das Programm druckt nichts.

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

Warum geschieht das?

War es hilfreich?

Lösung

Der Linker enthält nicht den Code in foo.a im endgültigen Programm, weil nichts in main.o Referenzen es. Wenn main.c neu geschrieben wird wie folgt, wird das Programm funktioniert:

//main.c

void foo();

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

Auch wenn mit einer statischen Bibliothek, die Reihenfolge der Argumente zu gcc (oder Linker) Kompilieren ist von Bedeutung:. Die Bibliothek nach den Objekten kommen muss, die darauf verweisen

gcc -o test main.o foo.a

Andere Tipps

Wie es hieß, nicht referenzierte Symbole aus dem Archiv machen es nicht an den Ausgang binär, weil Linker sie standardmäßig verwirft.

Um dieses Verhalten zu überschreiben, wenn die Verknüpfung mit statischen Bibliothek, --whole-archive / --no-whole-archive Optionen für den Linker verwendet werden können, wie folgt aus:

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

Dies zu aufgebläht binären führen kann, da alle Symbole von foo.a werden durch den Linker an den Ausgang enthalten sein, aber manchmal ist es gerechtfertigt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top