254 votes

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

Cet avertissement :

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

est un avertissement assez courant dans Visual Studio. J'aimerais en comprendre la raison exacte et savoir comment le traiter (le cas échéant).

Cela se produit dans un build de débogage, compilé avec /MDd . Le projet est lié à des choses comme Windows Version.dll y pdh.dll qui sont eux-mêmes liés à MSVCRT.dll . Évidemment, je n'ai pas les versions de débogage de ces derniers et 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 ?

301voto

Hans Passant Points 475940

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

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

Regardez les options du linker, Project + Properties, Linker, Command Line. 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é grâce à une directive de commentaire #pragma. C'est important, car vous obtiendriez d'horribles erreurs de liaison et des erreurs d'exécution difficiles à diagnostiquer s'il y avait un décalage entre l'option /M et la .lib que vous liez.

Vous verrez le message d'erreur que vous avez cité lorsqu'on demande à l'éditeur de liens de lier à msvcrt.lib. y libcmt.lib. Ce qui 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 peut fonctionner, mais il n'est pas rare qu'une foule d'autres erreurs d'édition de liens se produisent. Des choses comme errno qui est un extern int dans la version statique CRT mais qui est macro-edié à une fonction dans la version DLL. Beaucoup d'autres comme ça.

Pour résoudre ce problème de la bonne manière, trouvez le fichier .obj ou .lib que vous liez et qui a été compilé avec la mauvaise option /M. Si vous n'avez aucun indice, vous pouvez le trouver en recherchant "/MT" dans les fichiers .obj/.lib.

Btw : les exécutables Windows (comme version.dll) ont leur propre version CRT pour faire leur travail. Elle est située 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 a un nom différent (comme msvcrt90.dll).

3 votes

Grâce à ce post, j'ai continué à chercher un .lib qui utilisait encore /MDd et j'ai fini par en trouver un ! Merci, +1

74 votes

Une astuce que je viens d'apprendre pour retrouver les bibliothèques qui tirent les mauvaises bibliothèques CRT est d'ajouter /verbose:lib aux options supplémentaires du linker. Il montre l'ordre dans lequel les fichiers .lib sont chargés, ce qui vous permet de voir où le fichier incorrect a été inséré.

1 votes

Hans, c'est dangereux ? Si nous ne pouvons pas le corriger (nous recevons une librairie compilée de notre fournisseur), quelles sont les conséquences auxquelles nous pouvons être confrontés ?

53voto

Yochai Timmer Points 19802

Cela signifie que l'une des dlls dépendantes a été compilée avec un autre nom. bibliothèque d'exécution .

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

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

Pour en savoir plus sur cette erreur, cliquez sur ce lien :

warning LNK4098 : la librairie par défaut "LIBCD" est en conflit avec l'utilisation d'autres librairies

0 votes

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

1 votes

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

33voto

ForceMagic Points 1490

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

Yochai, si vous lisez ceci, lisez la note à la fin.


Pour l'article original, lire : warning LNK4098 : la librairie par défaut "LIBCD" est en conflit avec l'utilisation d'autres librairies

Erreur

LINK : warning LNK4098 : defaultlib "LIBCD" entre en conflit avec l'utilisation d'autres libs ; utiliser /NODEFAULTLIB:library

Signification

une partie du système a été compilée pour utiliser une bibliothèque standard (libc) à thread unique avec des informations de débogage (libcd) qui sont liées 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 maintenant plusieurs instances des mêmes fonctions.

  • Utilisez l'option /NODEFAULTLIB:lib de l'éditeur de liens. Ce n'est pas une solution complète, même si vous arrivez à lier votre programme de cette façon, vous ignorez un signe d'alerte : le code a été compilé pour différents environnements, une partie de votre code peut être compilé pour un modèle à un seul thread alors que d'autres codes sont multi-thread.

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

Dans ce dernier cas, comme il est mentionné dans l'article original, deux problèmes courants peuvent survenir :

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

  • Vous avez d'autres directives intégrées dans votre code : normalement, il s'agit du MFC. Si des modules de votre système sont liés au MFC, tous vos modules doivent nominalement être liés à la même version du MFC.

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


Note : Je voulais inclure le résumé du lien de Yochai Timmer dans sa propre réponse mais comme certaines personnes ont du mal à vérifier les modifications correctement, j'ai dû l'écrire dans une réponse séparée. Désolé

8voto

user1016736 Points 101

Je reçois ce message chaque fois que je veux créer une application en VC++.

Cliquez avec le bouton droit de la souris sur le projet, sélectionnez Propriétés puis, sous "Propriétés de configuration | C/C++ | Génération de code", sélectionnez "Multi-threaded Debug (/MTd)" pour la configuration Debug.

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

6voto

raehee Points 69

Cliquez avec le bouton droit de la souris sur le projet, sélectionnez Propriétés puis sous 'Propriétés de configuration | Linker | Input | Ignore specific Library et écrivez msvcrtd.lib

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X