wake-up-neo.com

Beheben von LNK4098: defaultlib 'MSVCRT' steht in Konflikt mit

Diese Warnung:

LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts
  with use of other libs; use /NODEFAULTLIB:library

ist eine ziemlich häufige Warnung in Visual Studio. Ich würde gerne den genauen Grund dafür und den richtigen Weg (wenn überhaupt) verstehen, damit umzugehen.

Dies geschieht in einem Debug-Build, der mit /MDd Kompiliert wurde. Das Projekt ist mit Fenstern Version.dll Und pdh.dll Verknüpft, die selbst mit MSVCRT.dll Verknüpft sind. Offensichtlich habe ich keine Debug-Versionen von diesen und kann sie nicht kompilieren.

Also habe ich der Linker-Befehlszeile /NODEFAULTLIB:MSVCRT Hinzugefügt und tatsächlich die Warnung entfernt. Aber was macht das eigentlich? Und warum ist es notwendig?

194
shoosh

Es gibt 4 Versionen der CRT-Linkbibliotheken in vc\lib:

  • libcmt.lib: Statische CRT-Linkbibliothek für einen Release-Build (/ MT)
  • libcmtd.lib: statische CRT-Linkbibliothek für einen Debugbuild (/ MTd)
  • msvcrt.lib: Bibliothek für das Release importieren DLL Version des CRT (/ MD)
  • msvcrtd.lib: Bibliothek für das Debug importieren DLL Version des CRT (/ MDd)

Sehen Sie sich die Linker-Optionen an: Projekt + Eigenschaften, Linker, Befehlszeile. Beachten Sie, dass diese Bibliotheken hier nicht erwähnt werden. Der Linker ermittelt automatisch, welche/M-Option vom Compiler verwendet wurde und welche .lib-Datei über eine # Pragma-Kommentar-Direktive verknüpft werden soll. Ein bisschen wichtig, Sie würden schreckliche Linkfehler bekommen und schwer zu diagnostizierende Laufzeitfehler, wenn es einen Konflikt zwischen der/M-Option und der .lib gab, mit der Sie verknüpfen.

Die von Ihnen angegebene Fehlermeldung wird angezeigt, wenn der Linker angewiesen wird, eine Verknüpfung zu msvcrt.lib nd libcmt.lib herzustellen. Was passiert, wenn Sie Code, der mit/MT kompiliert wurde, mit Code verknüpfen, der mit/MD verknüpft wurde. Es kann nur eine Version der CRT geben.

/ NODEFAULTLIB weist den Linker an, die # Pragma-Kommentaranweisung zu ignorieren, die aus dem kompilierten/MT-Code generiert wurde. Dies könnte funktionieren, obwohl eine Menge anderer Linker-Fehler nicht ungewöhnlich ist. Dinge wie errno, was ein externes Int in der statischen CRT-Version ist, aber zu einer Funktion in der DLL Version. Viele andere mögen das.

Beheben Sie dieses Problem auf die richtige Art und Weise. Suchen Sie die OBJ- oder LIB-Datei, die Sie verknüpfen und die mit der falschen/M-Option kompiliert wurde. Wenn Sie keine Ahnung haben, können Sie sie finden, indem Sie die .obj/.lib-Dateien nach "/ MT" durchsuchen.

Übrigens: Die ausführbaren Windows-Dateien (wie version.dll) haben eine eigene CRT-Version, um ihre Arbeit zu erledigen. Es befindet sich in c:\windows\system32, Sie können es nicht zuverlässig für Ihre eigenen Programme verwenden, seine CRT-Header sind nirgendwo verfügbar. Die von Ihrem Programm verwendete CRT DLL) hat einen anderen Namen (wie msvcrt90.dll).

249
Hans Passant

Dies bedeutet, dass eine der abhängigen DLLs mit einer anderen Laufzeitbibliothek kompiliert wird.

Projekt -> Eigenschaften -> C/C++ -> Codegenerierung -> Laufzeitbibliothek

Durchsuchen Sie alle Bibliotheken und stellen Sie sicher, dass sie auf die gleiche Weise kompiliert werden.

Mehr zu diesem Fehler in diesem Link:

Warnung LNK4098: defaultlib "LIBCD" widerspricht der Verwendung anderer Bibliotheken

43
Yochai Timmer

IMO dieser Link von Yochai Timmer war sehr gut und relevant, aber schmerzhaft zu lesen. Ich habe eine Zusammenfassung geschrieben.

Yochai, wenn du das jemals gelesen hast, lies bitte den Hinweis am Ende.


Lesen Sie für den ursprünglichen Beitrag: Warnung LNK4098: defaultlib "LIBCD" widerspricht der Verwendung anderer Bibliotheken

Error

LINK: Warnung LNK4098: defaultlib "LIBCD" widerspricht der Verwendung anderer Bibliotheken; benutze/NODEFAULTLIB: Bibliothek

Bedeutung

ein Teil des Systems wurde kompiliert, um eine einzelne Standardbibliothek (libc) mit Debug-Informationen (libcd) zu verwenden, die statisch verknüpft sind

ein anderer Teil des Systems wurde kompiliert, um eine Multithread-Standardbibliothek ohne Debug-Informationen zu verwenden, die sich in einer DLL und mit dynamischer Verknüpfung befindet

Wie zu lösen

  • Ignorieren Sie die Warnung, schließlich ist es nur eine Warnung. Ihr Programm enthält jetzt jedoch mehrere Instanzen derselben Funktionen.

  • Verwenden Sie die Linkeroption/NODEFAULTLIB: lib. Dies ist keine vollständige Lösung, auch wenn Sie Ihr Programm so verknüpfen lassen können, dass Sie ein Warnzeichen ignorieren: Der Code wurde für verschiedene Umgebungen kompiliert. Ein Teil Ihres Codes wurde möglicherweise für ein einzelnes Thread-Modell kompiliert, während sich ein anderer Code in diesem befindet Multi-Threaded.

  • [...] durchsuchen Sie alle Ihre Bibliotheken und stellen Sie sicher, dass sie die richtigen Verknüpfungseinstellungen haben

Im letzteren können, wie im ursprünglichen Beitrag erwähnt, zwei häufige Probleme auftreten:

  • Sie haben eine Drittanbieter-Bibliothek, die anders mit Ihrer Anwendung verknüpft ist.

  • In Ihrem Code sind andere Anweisungen eingebettet: Normalerweise ist dies das MFC. Wenn sich Module in Ihrem System mit MFC verbinden, müssen sich alle Ihre Module nominal mit derselben Version von MFC verbinden.

Stellen Sie in diesen Fällen sicher, dass Sie das Problem verstehen und sich für eine Lösung entscheiden.


Hinweis: Ich wollte diese Zusammenfassung von Yochai Timmers Link in seine eigene Antwort aufnehmen, aber da einige Leute Probleme haben, die Änderungen richtig zu überprüfen, musste ich sie in eine separate Antwort schreiben. Entschuldigung

30
ForceMagic

Ich erhalte dies jedes Mal, wenn ich eine Anwendung in VC++ erstellen möchte.

Klicken Sie mit der rechten Maustaste auf das Projekt, wählen Sie Eigenschaften und dann unter Konfigurationseigenschaften | C/C++ | Codegenerierung ', wählen Sie "Multithreaded-Debug (/ MTd)" für die Debug-Konfiguration.

Beachten Sie, dass dies die Einstellung für Ihre Release-Konfiguration nicht ändert. Sie müssen sich an derselben Stelle befinden und "Multi-Threaded (/ MT)" für Release auswählen.

7
user1016736

Klicken Sie mit der rechten Maustaste auf das Projekt, wählen Sie Eigenschaften und dann unter Konfigurationseigenschaften | Linker | Eingabe | Ignoriere bestimmte Bibliotheken und schreibe msvcrtd.lib

3
raehee