VS2010 statisch verknüpfen Problem
meine Firma hat kürzlich ein Upgrade von VS2005 auf VS2010. Wir haben ein riesiges Projekt, die verwendet eine Menge von Modulen, die miteinander verbunden sind statisch in die exe-Datei. Aber scheint es einige Probleme mit der Verlinkung in VS2010.
Erklären unser problem, wir haben gebaut, ein minimal-Beispiel-Projekt, welches aus wie auf dieser Grafik:
Es ist eine Anwendung, die eine Funktion aus der Bibliothek A. Bibliothek Ein Aufruf einer Funktion jeder Bibliothek B und Bibliothek C. mit Diesen zwei Bibliotheken, eine Funktion aufzurufen, bereitgestellt durch Bibliothek D.
Für Exe 1 unter Framework und Verweise wir alles, was zu false außer für Link Library-Abhängigkeiten, die auf true festgelegt ist. Der einzige Verweis Hinzugefügt wird, wird die Verknüpfung zu Bibliothek Ein. Für die einzelnen Bibliotheken werden alle Einstellungen auf false gesetzt. Bibliothek bekommt Verweise nur B und C, sowie solche zwei immer Verweise auf D nur. Bibliothek D hat keine Referenzen.
Beim erstellen der Anwendung, es funktioniert ohne Probleme. Die Anwendung bemerkt, dass Bibliothek a verwendet Eine Bibliothek B und C, die Bibliothek mit D, so dass Sie es weiß, hat sich die Verknüpfung von Bibliotheken, zu. Die libs verlinkt sind in der exe-Datei ohne Probleme.
Wir jetzt etwas ändern in, sagen wir mal, Bibliothek D. Nur ein kleiner Unterschied, nur ein Brief. Jetzt versuchen wir, bauen Sie die Anwendung erneut, es bemerkt die änderung und re-kompiliert Bibliothek D, aber: Es ist kein link um es nicht mehr. Das Ergebnis sind Verknüpfungsfehler in Bibliothek B und C, weil Sie Bibliothek D. Wir müssen laufen Rebuild erste, um zu zwingen, das komplette Gebäude und dann ist alles wieder verknüpft.
Dies geschieht sowohl für die minimal-Beispiel als auch für unser Hauptprojekt. Natürlich, wir können hinzufügen, die einzelnen Bibliotheken als zusätzliche Abhängigkeit für die exe aber es wäre schön, wenn es funktionieren würde, so wie es beim erstellen des Projekts zum ersten mal mit und arbeiten nach den änderungen im code. Uns ist aufgefallen, dass bei der Festlegung Verwenden, Bibliothek Abhängigkeit Eingänge zu wahr, dass es wieder funktioniert, aber dann ist es nicht link, der *.lib-Dateien, aber die *.obj-Dateien, die nicht ist, was wir wollen, natürlich.
Hat jemand vergleichbare Erfahrungen gemacht oder hat jemand eine Lösung für dieses Problem? Ist das ein fehlerhaftes Verhalten von VS2010?
TIA.
p.s.: Alle Bibliotheken und ausführbaren Dateien sind native C++.
Edit: (Workaround entnommen diese Website)
In der Datei %ProgramsFile%\MSBuild\Microsoft.cpp\v4.0\Microsoft.CPPBuild.Targets
es ist eine Linie
<Target Name="GetResolvedLinkLibs" Returns="@(LibFullPath)" DependsOnTargets="$(CommonBuildOnlyTargets)">
Wenn Sie sich ändern, die Linie zu
<Target Name="GetResolvedLinkLibs" Returns="@(LibFullPath)" DependsOnTargets="$(CommonBuildOnlyTargets);ResolvedLinkLib">
die Verknüpfung ordnungsgemäß funktioniert und alle benötigten libs verknüpft sind, ist implizit. Die linker-Ausgabe zeigt nicht nur lib_a.lib aber auch alle anderen gekettet libs, lib_b, lib_c, lib_d die zimmerreserviereung, ohne das Sie manuell Hinzugefügt, da die Abhängigkeiten zu den exe.
Scheint dies mehr ein workaround dann eine Lösung, vielleicht gibt es ein richtige Art und Weise zu erreichen implizite Verknüpfung.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie einen Blick auf folgende links:
Visual Studio 2010 nicht autolinking statische Bibliotheken von Projekten, die Abhängigkeiten so sollte es sein soll
Verhalten von Link-Library-Abhängigkeiten in 2010
Nicht aufgelöste Externe Verweise Beim Bauen eines VC++ - Projekt mit Verketteten Statischen Lib-Abhängigkeiten
Flexible Projekt-zu-Projekt-Referenzen
Ich weiß nur, dass ich hatte so ähnliche Situationen, die aufgrund der falschen Verwendung von Bibliotheken mit gleichen Namen aber mit andere Architektur. sagen wir, ich habe eine Dll (nennen wir es mydll.dll für x86 und importieren Sie es in mein Projekt, es wird funktionieren. Wenn ich das gleiche mit x64 dll (mit dem gleichen Namen mydll.dll) wird es funktionieren.
Aber wenn ich möchte beide Bibliotheken ist es nicht erlaubt, nur benennen Sie es in mydllx86.dll /mydllx64.dll. Ich KANN zählen jetzt beide libraries in Visual Studio. Aber beim kompilieren oder Neustart von visual studio, einer der beiden Bibliotheken werden unaccessable mehr.
In diesem Fall ich, vielleicht hilft es, einen Blick in die Bibliothek, die Architektur und die verwendeten namespaces /Api-Namen.
Hinsichtlich
Sind Sie ziemlich verloren in diesem dialog, wenn Sie basteln mit Framework und Verweise, das sind Einstellungen, die nur für verwalteten code. Der Begriff "Referenz" gilt nur für .NET-Assemblys. Der linker unterstützt keine Speicherung zusammengestellt verwalteten code in einer .lib. Ich werde von der Annahme, dass Sie tatsächlich ändern sich die linker-Einstellungen. Wenn Sie eine änderung in der Bibliothek D, dann müssen Sie auch ändern Sie die header-Datei. Die in sich selbst reicht aus, um B und C neu aufgebaut, da ein oder mehrere Quellcode-Dateien sollte #include diesen header.
Das einzige, was Link Library-Abhängigkeiten tut, ist automatisch eine .lib eine Abhängigkeit, es ist das gleiche als Linker + Eingabe, Zusätzliche Abhängigkeiten festlegen. Das aber erfordert, dass Sie explizit festlegen, Abhängigkeiten des Projekts. Der rechten Maustaste auf die B-Projekt, klicken Sie auf Projekt-Abhängigkeiten und tick D. Wiederholen Sie den Vorgang für C. Wiederholen Sie den Vorgang für Ein und kreuzen Sie B und C. Wiederholen Sie für die EXE und Haken A.
Dies ist jedoch selten, was Sie wollen, es macht die D Bibliothek, eingebettet in den B-und C-Bibliotheken. Und B und C erhalten, eingebettet in A. Die EXE-Datei hat jetzt nur noch eine Abhängigkeit auf A. Es funktioniert, aber es macht die .lib-Dateien, die unnötig bullig aus. Und Sie haben das problem, das Sie beschreiben, wenn Sie nicht setzen das Projekt Abhängigkeiten richtig, ein Umbau von D nicht dazu führen, dass es B und C, um erneut verknüpft werden.
Was Sie tun sollten, ist nicht, legen Sie die Abhängigkeiten zwischen den .libs, Sie haben keine. Jeder kann ohne das andere .libs vorhanden. Ein .lib ist nichts anderes als eine Tüte .obj-Dateien. Alles, was erforderlich ist, dass Sie alle 4 .lib-Projekte Abhängigkeiten der EXE-Projekt. Das macht Sie sicher, dass Sie gebaut werden, bevor der linker versucht link die EXE-Datei.
Beginnen wir zu sehen, dieses Problem wieder, nach dem Wechsel zu Visual Studio 2015 (und auch in VS2017). Das problem scheint nur zu existieren, in der folgenden Konfiguration:
Gibt es mehrere andere Projekte in der Projektmappe, die Nutzung A und B. Wenn etwas im Projekt B oder C ändert, werden viele dieser Projekte geben LNK4099 Warnungen.
In unserem Fall, die Lösung ist die Verwendung die folgenden:
Code Generation > Output-Dateien > Programm-Datenbank-Datei-Name: $(TargetDir)$(TargetName).pdb
Bibliothekar > allgemein - > Output-Datei: $(TargetDir)$(TargetName)$(TargetExt)
$(TargetDir) verwendet einen absoluten Pfad gegenüber dem Standard - $(OutDir) das war in unserem Fall relativ. Es scheint, dass Sie den richtigen Pfad verloren, mit mehreren Ebenen der Dereferenzierung.
Eine interessante Sache ist, wenn Sie wechseln Sie die Anzahl der threads kompilieren zu 1, es scheint nicht zu passieren (vielleicht eine Art race condition innerhalb von Visual Studio?).