Ich bin gerade (ziemlich kaum) von einer nicht trivialen Warnung aus Visual Studio 2010 (C ++) auf den Kopf geschlagen worden.
Die Zusammenstellung ergab folgende Ausgabe:
1 Debug \ is.obj: Warnung LNK4042: Objekt mehr als einmal angegeben; Extras ignoriert
1 Debug \ make.obj: Warnung LNK4042: Objekt mehr als einmal angegeben; Extras ignoriert
1 Debug \ view.obj: Warnung LNK4042: Objekt mehr als einmal angegeben; Extras ignoriert
1 identity.obj: Fehler LNK2019: ungelöstes externes Symbolvoid __cdecl test::identity::view(void)
(? view @ identity @ test @@ YAXXZ), auf das in der Funktion verwiesen wirdvoid __cdecl test::identity::identity(void)
(? identity @ 0test @@ YAXXZ)
1 identity.obj: Fehler LNK2019: ungelöstes externes Symbolvoid __cdecl test::identity::make(void)
(? make @ identity @ test @@ YAXXZ) in der Funktion referenziertvoid __cdecl test::identity::identity(void)
(? identity @ 0test @@ YAXXZ)
1 range.obj: Fehler LNK2019: ungelöstes externes Symbolvoid __cdecl test::range::is(void)
(? is @ range @ test @@ YAXXZ), auf das in der Funktion verwiesen wirdvoid __cdecl test::range::range(void)
(? range @ 0test) YAXXZ)
Linker-Fehler sind immer ein Problem beim Debuggen ... aber es gab ungelöste Referenzen, und so habe ich nachgesehen ... aber die Quelle ist wohlgeformt ... und schließlich hat es mich getroffen:
Meine Ordnerhierarchie sieht folgendermaßen aus:
src/
identity/
is.cpp
make.cpp
view.cpp
range/
is.cpp
make.cpp
view.cpp
und die Hierarchie in der Lösung auch (ich habe sie immer so eingerichtet, dass sie die "echte" Ordnerstruktur nachahmt).
Und die Diagnoseausgänge:
Debug\is.obj
Debug\make.obj
Debug\view.obj
Zusammen mit einer Warnung, die besagt, dass das .obj
zweimal an den Linker übergeben wurde und dass einer ignoriert wird.
Suchen Sie nicht mehr: Visual hat meine Ordnerhierarchie sauber reduziert und kann daher die Quelle nicht sauber kompilieren.
Im Moment denke ich nur daran, die Dateien umzubenennen, die das Problem abdecken sollten ...
... aber gibt es eine Möglichkeit, dass Visual Studio die Dateihierarchie NICHT reduziert?
quelle
Antworten:
Ich wollte nur die Antwort kreuzen, die meiner Meinung nach die Antwort ist, wenn Sie die Eigenschaften für das gesamte Projekt öffnen und den Wert
C/C++ -> Output Files -> "Object File Name"
wie folgt ändern :$ (IntDir) /% (RelativeDir) /
Ich glaube, dass dies unter VS 2010 alle Objektdateien eindeutig macht (da ich glaube, dass Windows es Ihnen unter verrückten Umständen nicht erlaubt, zwei Dateien mit demselben Namen im selben Verzeichnis zu haben). Bitte überprüfen Sie auch die Details hier .
quelle
cl.exe
in CLI verwende?Ich hatte ein ähnliches Problem mit der Linker-Warnung LNK4042: Objekt mehr als einmal angegeben; Extras ignoriert . In meinem Fall hat Visual Studio versucht, sowohl Header- als auch Quelldateien mit demselben Namen zu kompilieren -
MyClass.h
undMyClass.cpp
. Es ist passiert, weil ich die.cpp
Datei in umbenannt habe.h
und Visual Studio verwirrt war. Ich habe das Problem beim Betrachten der Compiler-Protokolle imDebug
Verzeichnis bemerkt . Zum Auflösen entfernen Sie einfach die.h
Datei aus dem Projekt und fügen Sie sie erneut hinzu.quelle
foo.h
Datei in Ihrem Lösungs-Explorer klicken und "Elementtyp" auf "C / C ++ - Header" anstatt auf "C / C ++ - Compiler" setzen.CLInclude
EintragKlicken Sie mit der rechten Maustaste auf die CPP-Datei im Projektmappen-Explorer, Eigenschaften, C / C ++, Ausgabedateien, Objektdateiname. Die Standardeinstellung ist
$(IntDir)\
, dass dies die Abflachung bewirkt. Die gesamte OBJ-Datei wird in $ (IntDir), dem Verzeichnis "Debug" in der Debug-Konfiguration, abgelegt.Sie können beispielsweise die Einstellung ändern
$(IntDir)\is2.obj
. Oder wählen Sie alle Dateien aus einer Gruppe aus (verwenden Sie Umschalt + Klicken) und ändern Sie die Einstellung beispielsweise in$(IntDir)\identity\
Oder Sie können den .cpp-Dateinamen so ändern, dass sich .obj-Dateien nicht gegenseitig überschreiben. Dateien mit genau demselben Namen in zwei Verzeichnissen zu haben, ist etwas seltsam.
Sie können auch mehrere Projekte erstellen, z. B. .lib-Projekte für die Dateien in Identität und Bereich. Wird beispielsweise häufig in Makefile-Projekten durchgeführt. Das macht das Verwalten der Kompilierungs- und Verknüpfungseinstellungen jedoch schwieriger, es sei denn, Sie verwenden Projekteigenschaftenblätter.
quelle
$(IntDir)
pro Datei in einem Eigenschaftenblatt festzulegen? Ich weiß, dass Sie es für das gesamte Projekt in einem Eigenschaftenblatt festlegen können, aber ich weiß nicht, ob Sie es basierend auf dem Pfad der zu kompilierenden Datei festlegen können. (Meine Vermutung ist nein, aber ich bin ein kompletter MSBuild-Neuling)Klicken Sie mit der rechten Maustaste auf Header-Datei -> Eigenschaft -> ItemType (wählen Sie C / C ++ - Header ). Machen Sie dasselbe mit der Cpp-Datei, aber wählen Sie C / C ++ Compiler (es funktioniert für mich)
quelle
Ich verwende $ (IntDir) \% (Directory) \ unter C / C ++ -> Ausgabedateien -> "Object File Name".
quelle
Ich hatte dieses Problem mit stdafx.cpp. Irgendwie wurde stdafx.cpp dupliziert, also gab es eine zweite StdAfx.cpp (beachten Sie den anderen Fall).
Nachdem ich die StdAfx.cpp entfernt hatte, funktionierte alles einwandfrei!
Verwenden von VS 2010.
quelle
Alternativ zum Löschen und Erstellen einer neuen Datei können Sie die Einstellungen zum Kompilieren / Einschließen ändern.
Gehen Sie zu Ihrer Datei project.vcxproj , öffnen Sie sie mit einem Editor und suchen Sie die HTML-ähnliche Zeile
<ItemGroup>
.Es sollte ungefähr so aussehen:
<ItemGroup> <ClCompile Include="implementation.cpp" /> </ItemGroup>
und
<ItemGroup> <ClInclude Include="declaration.hpp" /> </ItemGroup>`
Angenommen, Ihre Implementierungsdateien sind .cpp und Ihre Deklarationen sind .hpp. Stellen Sie sicher, dass alle Ihre Implementierungsdateien zwischen dem ersten Abschnitt aufgelistet sind, wenn Sie mehr als eine haben, und ebenfalls für den zweiten Abschnitt für mehrere Deklarationsdateien.
quelle
Früher habe ich in den gleichen Projekt haben .c und CPP - Dateien mit den gleichen Dateinamen . Die Dateien befanden sich überall in Ordnern, und die von anderen bereitgestellten Lösungen verursachten ein Durcheinander und die Hölle der Ordner (in meinem Fall). Selbst Release- Builds würden Debug- Builds überschreiben !
Eine gute (nicht perfekte) Lösung wäre die Verwendung von $ (ParentName). Aus irgendeinem Grund wurde es jedoch aus späteren Versionen von Visual Studio (2015+) entfernt.
Was ich jetzt erfolgreich benutze, ist: $ (IntDir)% (Dateiname)% (Erweiterung) .obj
Dies trennt zumindest die von .c erstellten Objektdateien von .cpp .
quelle