Warum funktioniert __attribute__((constructor)) nicht in einer statischen Bibliothek?

Lesezeit: 2 Minuten

Benutzer-Avatar
Jay Conrod

Im folgenden Beispiel soll das Programm drucken "foo called\n":

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

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

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

Wenn das Programm so kompiliert ist, funktioniert es:

gcc -o test main.c foo.c

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

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

Warum passiert das?

  • Warum die Abwertungen? Ist etwas falsch?

    – Jay Conrod

    29. Juli 2009 um 19:41 Uhr

  • Ich bin mir nicht sicher (ich nicht!), aber vielleicht hat jemand Anstoß daran genommen, dass Sie Ihre eigene Frage so schnell beantwortet haben?

    – DaveR

    29. Juli 2009 um 20:52 Uhr

  • Hmm, ich wollte der Seite nur einen nützlichen Hinweis für ein nicht offensichtliches Problem hinzufügen. Die FAQ zeigt an, dass es eine gute Sache ist, die eigene Frage zu beantworten (es steht eigentlich im ersten Abschnitt).

    – Jay Conrod

    29. Juli 2009 um 22:32 Uhr

Der Linker fügt den Code in foo.a nicht in das endgültige Programm ein, da nichts in main.o darauf verweist. Wenn main.c wie folgt umgeschrieben wird, wird das Programm funktionieren:

//main.c

void foo();

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

Auch beim Kompilieren mit einer statischen Bibliothek ist die Reihenfolge der Argumente für gcc (oder den Linker) von Bedeutung: Die Bibliothek muss nach den Objekten kommen, die sie referenzieren.

gcc -o test main.o foo.a

Wie bereits erwähnt, gelangen nicht referenzierte Symbole aus dem Archiv nicht in die Ausgabebinärdatei, da der Linker sie standardmäßig verwirft.

Um dieses Verhalten beim Linken mit einer statischen Bibliothek zu überschreiben, --whole-archive/--no-whole-archive Optionen für den Linker können wie folgt verwendet werden:

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 kann zu einer aufgeblähten Binärdatei führen, da alle Symbole aus foo.a wird vom Linker in die Ausgabe aufgenommen, aber manchmal ist es gerechtfertigt.

1382140cookie-checkWarum funktioniert __attribute__((constructor)) nicht in einer statischen Bibliothek?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy