Verknüpfung Windows-DLL-Dateien, statische Bibliotheken, die mit CMake ohne hand-crafting nicht aufgelöstes symbol Namen
Die Situation
Ich bin mit Visual Studio 2008 SP1 (Professional-Edition, die sowohl für 32-bit und 64-bit
baut). Ich Suche eine Abhilfe für das, was ich glaube, ist ein sehr
wenig hilfreich "Einschränkung" in Visual Studio.
Ich finde es ziemlich
verwunderlich, dass die Visual Studio linker und compiler nicht tut, dieses Recht auf DLL-Datei
Zeitpunkt der Erstellung, um automatisch einen scan alle angegebenen statischen Bibliotheken
für alle exportierten Symbole in der gleichen Art und Weise gegeben, in Aufbau eines
Import-und Export-Datei-Bibliothek und in ein StackOverflow
Kommentar. Ich bestätigte, dass es nicht reicht, einfach anzuwenden
__declspec(dllexport)
und __declspec(dllimport)
Attribute
Klassen -, Funktions -, und Daten-Deklarationen in den Dateien, aus denen die
statische Bibliotheken.
Den linker scan nicht alle statischen Bibliotheken
für exportierte Symbole und so nicht ziehen Sie in die DLL-Datei (die Symbole
haben, verwiesen werden, die durch .obj
Dateien, die auf der DLL-link-Kommando-Zeile oder
durch andere Mittel, die ich unten zeigen). Ohne explizite Verweise auf jede
exportierte symbol, die DLL-Datei immer noch angelegt werden, aber Ihr Zusammenhang
import-Bibliothek-Datei wird nicht erstellt.
Von dem, was ich sammeln können, empfiehlt Microsoft den Benutzern mit LIB.EXE
zum erstellen der DEF - Datei, aber leider, die LIB.EXE Seite
gilt eine Einschränkung:
Beachten Sie, dass wenn Sie erstellen Sie Ihre Bibliothek importieren in eine erste Schritt
bevor Sie Ihre.dll
, müssen Sie passieren die gleiche Reihe von Objekt-Dateien
beim Bau der.dll
, wie Sie übergeben, wenn der Bau der import
Bibliothek.
Dass ist eine unglückliche Einschränkung gegeben, dass ich mich auch mit CMake in
meine neue build-Umgebung. CMake blendet die details von dem, was eigentlich
an den linker übergeben (und ich finde, dass es eine gute Sache in 99% der
Zeit), aber in diesem Fall, ich brauche, um Zugang zu einigen Informationen auf
CMake Ausführungszeit, danach nicht mit der hand gemachte scripts oder
andere zerbrechliche skulduggery.
Die Fragen:
Wie kann ich das erzwingen der DLL-linker
beheben Sie alle exportierten Symbole in allen statischen Bibliotheken, aus denen die
DLL-Datei, die nicht geht, zu führen zerbrechlichkeit und zusätzliche bauen
Logik Wartung Aufgaben? Denken in Bezug auf die voll-Automatisierung hier, und
halten Sie im Verstand, ich brauche zu tun diese mehrere Male
verschiedenen DLL.
Meine Fragen sind:
-
Wie bekomme ich die set-object-Dateien und statische Bibliotheken verwendet
auf der letzten DLL-link-Befehlszeile mithilfe von CMake syntax allein? -
Wird die Reihenfolge der aufgelisteten Dateien auf LIB.EXE Linie (die man verwendet
zum generieren der DEF - Datei) muss exakt übereinstimmen, die verwendet, um auf
die DLL-link-Zeile? -
Gibt es andere Schwierigkeiten, ich kann auch aus der Verwendung
der LIB.EXE Ansatz zum generieren der DEF Datei? -
Gibt es einen besseren Weg zu gehen, was diese nicht benötigen
das aufrufen eines separaten Programms, wie LIB.EXE, vor Aufruf der
letzten link? Ich bin besorgt über die zusätzlichen build-Aufwand jenseits der
link selbst für LIB.EXE Scannen Sie alle der statische Bibliotheken
wieder obwohl es gerade schrieb Sie in gesonderten Ausführungen.
Die Nicht-Antworten:
Im folgenden sind die Lösungen, die ich nicht berücksichtigen können jetzt:
-
Manuelles angeben der nicht referenzierte Symbole, die irgendwo auf anderen als
in der ursprünglichen.h
oder.cpp
- Dateien, wie zu tun, dass wird
brechen jedes mal, wenn ein Entwickler vergisst, die Datei zu aktualisieren, die Listen
die (womöglich name-Mangling) symbol-name. Und es wird brechen
mit nicht-user-freundlich-linker-Fehlern über nicht aufgelöste Symbole
das wird teuer für Entwickler zum Debuggen. Diese nicht-Antwort
umfasst die folgenden Ansätze:-
Explizit Hinzugefügt
.obj
Dateien in der DLL-link-Kommando-Zeile
(Varianten dieser gehören das hinzufügen von "fake".obj
Dateien
dummy Verweise auf die ansonsten nicht referenzierte, aber exportiert
Symbole (und beachten Sie, dass dies ist, was meine alte build-Umgebung
heute, und es stinkt) und, -
Handarbeit DEF Dateien die nicht referenzierte, aber
exportiert Symbole, und, -
Linker-command-line-Optionen, die speziell zu verweisen, die
nicht referenzierte, aber die exportierten Symbole.
-
-
Stoppen Sie die Verwendung statischer Bibliotheken insgesamt. Ich kann das nicht in der
kurzfristig, da es zu viel von einem Strukturwandel aus den alten
build-Umgebung bin ich Weg von. Es ist sehr wahrscheinlich werde ich
diesen Weg in die Zukunft, nachdem alle Reste der alten bauen,
Umgebung sind in den "Papierkorb", aber das ist nicht mein Fokus hier.
Referenz material:
- Exportieren aus einer DLL Mithilfe von DEF-Dateien
- Modul-Definition (.def) Dateien
- PRB: Kann nicht den Export von Statischen Bibliotheken w/_declspec(dllexport)
- dumpbin.exe Symbole /option
- lib.exe Optionen
- Aufbau einer Bibliothek Importieren und Exportieren, die Datei
- CMake LINK_FLAGS target-Eigenschaft
- Die Mozilla-build-system verwendet nicht-Antwort 1.1 und jeder so oft, jemand hat zu erinnern, zu aktualisieren
dlldeps.cpp
- Datei, so dass Sie die richtigen Dinge bekommen exportiert. Ihr plan ist die Umstellung auf nicht-Antwort 2. - Ich kann mir nicht helfen, aber das ist einer von den am meisten gut-SCHRIFTLICHEN Fragen, die ich je gesehen habe. Viel Glück.
- Ein Teil der dll-linker, der job ist nicht enthalten Dinge, die nicht enthalten sein müssen: d.h. referenzierte Funktionen in statischen Bibliotheken. Also, wenn Sie nicht ausdrücklich Bezug einer Funktion in eine statische lib von einer Funktion, die dllexport ' ed, es sollte auch gar nicht aufgenommen werden in die endgültigen dll, geschweige denn exportiert werden. Ich denke, die richtige Antwort für Sie ist nicht-Antwort 2, jedoch schmerzhaft es sein kann, um dorthin zu gelangen... ich denke, es wird beweisen, weniger schmerzhaft als die Aufrechterhaltung jede Art von automatischen Synchronisations-framework kommt man vielleicht auf ein custom-build-tool-Lösung.
- Vielen Dank an alle. Ich werde live mit der nicht-Antwort #1.1 für jetzt, bis ich das budget zur Umsetzung nicht-Antwort #2, #2 fühlt sich einfach wie der richtige Weg zu gehen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin nur der Beantwortung deutlich zu machen, Ihr Gefühl, nicht zu verwenden, statische Bibliotheken korrekt ist.
DLRdave sagte es bereits in die Kommentare, Ihr build-system missbraucht wird, indem LIB-Dateien. Eine LIB-Datei ist ähnlich wie eine Reale Bibliothek, die Sie nur zu Fuß aus mit den Dingen, die Sie bitten, nicht alles in der Bibliothek.
Wenn es eine Lücke in der Visual Studio 2008-Werkzeug-set, es ist, dass es nicht unterstützt, teilweise verknüpfen. Die Eingabe in eine teilweise Verbindung ist ein Satz von OBJ-Dateien und die Ausgabe ist eine einzelne OBJ-Datei enthält den code und die Daten aus der Eingabe OBJ-Dateien.
Den Unterschied zwischen einem Archiv/Bibliothek und eine teilweise Verbindung ist beschrieben für g++ in der Antwort auf diese Frage: g++ teilweise Verknüpfung anstelle der Archive?, wo der GNU linker (ld) unterstützt, die teilweise Verknüpfung.
Als mögliche Kurzfristige Klimaschutz - persönlich, ich würde habe versucht, verwenden Sie scripting, um dynamisch erstellen Sie die DEF-Datei zu erstellen Zeit, indem Sie
LIB /List
oderDUMPBIN /ARCHIVEMEMBERS
um die obj-Dateien undLIB /DEF
zu generieren, die die DEF-Datei aus der Liste. Oder, wie ich annehme_declspec(dllexport
) verwendet wird, könnten Sie auch verwendet werdenDUMPBIN /DIRECTIVES
gesucht/EXPORT
gebaut und die DEF-Datei selbst.add_library(... STATIC ...)
zur Umsetzung einer solchen DEF generation-Mechanismus. Ich muss zu geben, dass einige mehr dachte.