web-dev-qa-db-fra.com

Résolution de LNK4098: conflits par défaut 'MSVCRT' 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 comprendre la raison exacte et la bonne manière (le cas échéant) de le gérer.

Cela revient dans une construction de débogage, compilée avec /MDd. Le projet est lié à des éléments tels que windows Version.dll et pdh.dll qui sont eux-mêmes liés à MSVCRT.dll. Évidemment, je n'ai pas les versions de débogage de ceux-ci et je ne peux pas les compiler.

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

194
shoosh

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

  • libcmt.lib: bibliothèque de liens CRT statique pour une version release (/ 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 version du CRT (/ MD)
  • msvcrtd.lib: bibliothèque d'importation pour la version de débogage DLL du CRT (/ MDd)

Examinez 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 fichier .lib doit être lié par le biais d'une directive de commentaire #pragma. Un peu important, vous obtiendrez d’horribles erreurs de liens et il sera difficile de diagnostiquer les erreurs d’exécution s’il y avait une incompatibilité entre l’option/M et le fichier .lib auquel vous liez.

Vous verrez le message d'erreur que vous avez cité quand il est demandé à l'éditeur de lien de créer un lien vers msvcrt.lib and libcmt.lib. Ce qui se produira si vous liez un code compilé avec/MT avec un code lié à/MD. Il ne peut y avoir qu'une seule version du tube cathodique.

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

Corrigez ce problème correctement, recherchez le fichier .obj ou .lib que vous liez et qui a été compilé avec la mauvaise option/M. Si vous n'avez pas la moindre idée, vous pouvez le trouver en récupérant les fichiers .obj/.lib pour "/ MT"

Btw: les exécutables Windows (comme version.dll) ont leur propre version de CRT pour effectuer leur travail. Il se trouve 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. Le CRT DLL utilisé par votre programme a un nom différent (comme msvcrt90.dll).

249
Hans Passant

Cela signifie qu'une des dll dépendantes est compilée avec un autre 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 assurez-vous qu'elles sont compilées de la même manière.

Plus d'informations sur cette erreur dans ce lien:

avertissement LNK4098: la librairie par défaut "LIBCD" entre en conflit avec l'utilisation d'autres libs

43
Yochai Timmer

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

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


Pour le message d'origine, lisez: Avertissement: LNK4098: la librairie par défaut "LIBCD" entre en conflit avec l'utilisation d'autres bibliothèques

Erreur

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

Sens

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

alors 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 un DLL et utilise un lien dynamique

Comment résoudre

  • Ignorer l'avertissement, après tout, il ne s'agit que d'un avertissement. Cependant, votre programme contient maintenant 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 faire en sorte que votre programme crée un lien 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ée pour un seul modèle à thread alors que d'autres sont en code. multi-threaded.

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

Comme cela a été mentionné dans le message 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 à MFC, tous vos modules doivent être liés de manière nominale à la même version de MFC.

Pour ces cas, assurez-vous de 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 à examiner correctement les modifications, j'ai dû l'écrire dans une réponse distincte. Désolé

30
ForceMagic

Je l’obtiens à 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 la 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 Release - vous devez vous rendre au même emplacement et sélectionner "Multi-threaded (/ MT)" pour Release.

7
user1016736

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

3
raehee