Résolution de LNK4098: defaultlib 'MSVCRT' entre en conflit avec


216

Cet avertissement:

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

est un avertissement assez courant dans Visual Studio. Je voudrais comprendre la raison exacte de cela et la bonne façon (le cas échéant) de le gérer.

Cela apparaît dans une version de débogage, compilée avec /MDd. Le projet est lié à des choses comme les fenêtres Version.dllet avec pdh.dlllesquelles elles sont liées MSVCRT.dll. Évidemment, je n'en ai pas les versions de débogage et je ne peux pas les compiler.

J'ai donc ajouté /NODEFAULTLIB:MSVCRTà la ligne de commande de l'éditeur de liens et cela a effectivement supprimé l'avertissement. Mais qu'est-ce que cela fait réellement? Et pourquoi est-ce nécessaire?

Réponses:


273

Il existe 4 versions des bibliothèques de liens CRT présentes dans vc \ lib:

  • libcmt.lib: bibliothèque de liens CRT statiques pour une version (/ MT)
  • libcmtd.lib: bibliothèque de liens CRT statiques pour une version de débogage (/ MTd)
  • msvcrt.lib: bibliothèque d'importation pour la version DLL de sortie du CRT (/ MD)
  • msvcrtd.lib: bibliothèque d'importation pour la version DLL de débogage du CRT (/ MDd)

Regardez les options de l'éditeur de liens, Projet + Propriétés, Éditeur de liens, Ligne de commande. Notez que ces bibliothèques ne sont pas mentionnées ici. L'éditeur de liens détermine automatiquement quel commutateur / M a été utilisé par le compilateur et quel .lib doit être lié via une directive de commentaire #pragma. Un peu important, vous obtiendriez des erreurs de lien horribles et des erreurs d'exécution difficiles à diagnostiquer s'il y avait un décalage entre l'option / M et le .lib avec lequel vous vous connectez.

Vous verrez le message d'erreur que vous avez cité lorsque l'éditeur de liens est invité à se lier à msvcrt.lib et libcmt.lib. Cela se produira si vous liez du code qui a été compilé avec / MT avec du code qui a été lié avec / MD. Il ne peut y avoir qu'une seule version du CRT.

/ NODEFAULTLIB indique à l'éditeur de liens d'ignorer la directive de commentaire #pragma qui a été générée à partir du code compilé / MT. Cela pourrait fonctionner, bien qu'une multitude d'autres erreurs de l'éditeur de liens ne soient pas rares. Des choses comme errno , qui est un int externe dans la version statique CRT mais macro-ed à une fonction dans la version DLL. Beaucoup d'autres aiment ça.

Eh bien, corrigez ce problème de la bonne manière, recherchez le fichier .obj ou .lib que vous liez qui a été compilé avec la mauvaise option / M. Si vous n'avez aucune idée, vous pouvez le trouver en saisissant les fichiers .obj / .lib pour "/ MT"

Btw: les exécutables Windows (comme version.dll) ont leur propre version CRT pour faire leur travail. Il est situé dans c: \ windows \ system32, vous ne pouvez pas l'utiliser de manière fiable pour vos propres programmes, ses en-têtes CRT ne sont disponibles nulle part. La DLL CRT utilisée par votre programme porte un nom différent (comme msvcrt90.dll).


2
Grâce à ce post, j'ai continué à chercher un .lib qui utilisait toujours / MDd et j'en ai finalement trouvé un! Merci, +1
ceztko

64
Une astuce que je viens d'apprendre pour retrouver les bibliothèques qui récupèrent les mauvaises bibliothèques CRT est d'ajouter /verbose:libaux options supplémentaires de l'éditeur de liens. Il montre l'ordre dans lequel les fichiers .lib sont chargés, vous permettant de voir où le fichier incorrect a été
récupéré

1
Hans, est-ce dangereux? Si nous ne pouvons pas le réparer (nous obtenons une bibliothèque compilée de notre fournisseur), à quelles conséquences pouvons-nous faire face?
Ivan Nikitin

3
J'ai trouvé le commentaire de @obmarg utile mais je ne savais toujours pas comment utiliser la sortie verbeuse jusqu'à ce que je trouve msdn.microsoft.com/en-us/library/aa267384(v=vs.60).aspx qui dit que la sortie verbeuse sera vous indique uniquement toutes les bibliothèques d'exécution impliquées dans le problème de lien. Vous devez ensuite déterminer quelle entrée de lien a été compilée avec la bibliothèque Runtime en conflit.
buzz3791

4
@ buzz3791 utilisez / verbose au lieu de / verbose: lib. Les informations affichées incluent le processus de recherche de bibliothèque et répertorient chaque bibliothèque et nom d'objet (avec chemin d'accès complet), le symbole en cours de résolution à partir de la bibliothèque et une liste d'objets qui font référence au symbole. / verbose peut afficher toutes les informations dont vous avez besoin pour trouver le méchant à l'origine des conflits.
Yang Kui

46

Cela signifie que l'une des DLL dépendantes est compilée avec une bibliothèque d'exécution différente .

Projet -> Propriétés -> C / C ++ -> Génération de code -> Bibliothèque d'exécution

Parcourez toutes les bibliothèques et vérifiez qu'elles sont compilées de la même manière.

Plus d'informations sur cette erreur dans ce lien:

avertissement LNK4098: defaultlib "LIBCD" entre en conflit avec l'utilisation d'autres bibliothèques


C'était la raison de l'erreur! Merci pour le conseil.
rkachach

1
C'est la meilleure réponse pour les programmeurs moins expérimentés.
méolique

32

IMO ce lien de Yochai Timmer était très bon et pertinent mais douloureux à lire. J'ai écrit un résumé.

Yochai, si jamais vous lisez ceci, veuillez voir la note à la fin.


Pour le message d'origine, lisez: avertissement LNK4098: defaultlib "LIBCD" entre en conflit avec l'utilisation d'autres bibliothèques

Erreur

LINK: avertissement LNK4098: defaultlib "LIBCD" entre en conflit avec l'utilisation d'autres bibliothèques; utiliser / NODEFAULTLIB: bibliothèque

Sens

une partie du système a été compilée pour utiliser une bibliothèque standard à thread unique (libc) avec des informations de débogage (libcd) qui est liée statiquement

tandis qu'une autre partie du système a été compilée pour utiliser une bibliothèque standard multithread sans informations de débogage qui réside dans une DLL et utilise la liaison dynamique

Comment résoudre

  • Ignorez l'avertissement, après tout, ce n'est qu'un avertissement. Cependant, votre programme contient désormais plusieurs instances des mêmes fonctions.

  • Utilisez l'option de l'éditeur de liens / NODEFAULTLIB: lib. Ce n'est pas une solution complète, même si vous pouvez obtenir votre programme pour lier de cette façon, vous ignorez un signe d'avertissement: le code a été compilé pour différents environnements, une partie de votre code peut être compilé pour un modèle à thread unique tandis qu'un autre code est multi-thread.

  • [...] parcourez toutes vos bibliothèques et assurez-vous qu'elles ont les bons paramètres de lien

Dans ce dernier, comme cela a été mentionné dans le message d'origine, deux problèmes communs peuvent survenir:

  • Vous disposez d'une bibliothèque tierce qui est liée différemment à votre application.

  • Vous avez d'autres directives intégrées dans votre code: normalement c'est le MFC. Si des modules de votre système sont liés à MFC, tous vos modules doivent théoriquement être liés à la même version de MFC.

Dans ces cas, assurez-vous de bien comprendre le problème et de choisir parmi les solutions.


Remarque: je voulais inclure ce résumé du lien de Yochai Timmer dans sa propre réponse, mais comme certaines personnes ont du mal à réviser correctement les modifications, j'ai dû l'écrire dans une réponse distincte. Désolé


7

J'obtiens ceci chaque fois que je veux créer une application dans VC ++.

Cliquez avec le bouton droit sur le projet, sélectionnez Propriétés puis sous «Propriétés de configuration | C / C ++ | Génération de code ', sélectionnez "Débogage multithread (/ MTd)" pour la configuration du débogage.

Notez que cela ne modifie pas le paramètre de votre configuration de version - vous devrez vous rendre au même emplacement et sélectionner "Multi-thread (/ MT)" pour la version.


4

Cliquez avec le bouton droit sur le projet, sélectionnez Propriétés puis sous «Propriétés de configuration | Linker | Entrée | Ignorer une bibliothèque spécifique et écrire msvcrtd.lib

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.