2010-11-14 4 views
6

Ich habe ein Programm, myprogram, die mit einer statischen Convenience-Bibliothek verbunden ist, rufen Sie libconvenience.a, die eine Funktion enthält, func(). Die Funktion func() wird nirgendwo in myprogram aufgerufen; Es muss in der Lage sein, aus einer Plugin-Bibliothek, plugin.so, aufgerufen werden. Das Symbol func() wird nicht dynamisch in myprogram exportiert. Wenn ich renneSymbole aus Convenience-Bibliothek nicht in executable

nm myprogram | grep func 

bekomme ich nichts. Aber es fehlt nicht aus libconvenience.a:

nm libconvenience/libconvenience.a | grep func
00000000 T func

I auto verwenden, aber wenn ich den letzte Verknüpfung Schritt von Hand auf der Kommandozeile statt, es funktioniert auch nicht:

gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/libconvenience.a `pkg-config --libs somelibraries` 

Allerdings, wenn ich das Programm wie folgt verknüpfen, die Verwendung einer Komfort-Bibliothek Skipping und die Verknüpfung der Objektdateien, die in 01 gegangen wäredirekt, func() zeigt in myprogram up 's Symbolen, wie es soll:

gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/*.o `pkg-config --libs somelibraries` 

Wenn ich einen Dummy-Aufruf func() irgendwo in myprogram hinzufügen, dann func() zeigt auch in myprogram up' s Symbolen. Aber ich dachte, dass --export-dynamic sollte alle Symbole exportieren, unabhängig davon, ob sie im Programm verwendet wurden oder nicht!

Ich bin mit auto 1.11.1 und gcc 4.5.1 auf Fedora 14. Ich auch plugin.so bin mit Libtool 2.2.10 zu bauen (aber nicht die Bequemlichkeit Bibliothek.)

ich nicht vergessen, zu setzen -Wl,--export-dynamic in myprogram_LDFLAGS, noch habe ich vergessen, die Quelle zu setzen, die func() in libconvenience_a_SOURCES enthält (einige googeln legt nahe, dass diese häufige Ursachen für dieses Problem sind.)

Kann jemand mir helfen, zu verstehen, was hier vor sich geht?

Antwort

3

Ich habe es geschafft, es zu lösen. Es war diese Notiz von John Calcote ausgezeichneten Autotool Buch, das ich in der richtigen Richtung:

Linkers auf das binäre Produkt explizit auf der Kommandozeile angegeben jede Objektdatei hinzufügen, aber sie extrahieren nur aus Archiven der Objektdateien, die werden tatsächlich im verknüpften Code referenziert.

Um diesem Verhalten entgegenzuwirken, kann man das Flag --whole-archive für libtool verwenden. Dies führt jedoch dazu, dass alle Symbole aus allen Systembibliotheken ebenfalls eingezogen werden, was zu vielen doppelten Symboldefinitionsfehlern führt.Also --whole-archive muss direkt vor libconvenience.a auf der Linker-Befehlszeile sein, und es muss von --no-whole-archive gefolgt werden, so dass die anderen Bibliotheken nicht auf diese Weise behandelt werden. Das ist ein bisschen schwierig, da auto und libtool nicht wirklich Ihre Fahnen in der gleichen Reihenfolge auf der Kommandozeile garantieren zu halten, aber diese Linie in Makefile.am hat den Trick:

myprogram_LDFLAGS = -Wl,--export-dynamic \ 
    -Wl,--whole-archive,libconvenience/libconvenience.a,--no-whole-archive 
0

Wenn Sie func brauchen, um in plugin.so zu sein, sollten Sie versuchen, es dort zu finden, wenn möglich. Convenience-Bibliotheken sollen genau das sein - eine Annehmlichkeit, um als Zwischenschritt eine Verknüpfung zu einer ausführbaren Datei oder einer Bibliothek herzustellen.

+0

Das stimmt, aber ich brauche ausdrücklich func _nicht_ zu Sei im Plugin, weil func Teil einer API ist, die mehrere Plugins aufrufen müssen. Die Plugins wurden woanders geschrieben und ich versuche lokale Modifikationen zu vermeiden. – ptomato