Risoluzione di LNK4098: defaultlib ‘MSVCRT’ è in conflitto con

Questo avviso:

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

è un avviso abbastanza comune in Visual Studio. Mi piacerebbe capire la ragione esatta e il modo giusto (se non del tutto) per gestirlo.

Questo appare in una build di debug, compilata con /MDd . Il progetto è collegato a cose come Windows Version.dll e pdh.dll che si collegano con MSVCRT.dll . Ovviamente, non ho le versioni di debug di questi e non posso compilarli.

Così ho aggiunto /NODEFAULTLIB:MSVCRT alla riga di comando del linker e in realtà ha rimosso l’avviso. Ma cosa fa veramente questo? E perché è necessario?

Esistono 4 versioni delle librerie di collegamento CRT presenti in vc \ lib:

  • libcmt.lib: libreria di collegamento CRT statico per una versione di rilascio (/ MT)
  • libcmtd.lib: libreria di collegamento CRT statico per una build di debug (/ MTd)
  • msvcrt.lib: libreria di importazione per la versione DLL di rilascio del CRT (/ MD)
  • msvcrtd.lib: libreria di importazione per la versione debug DLL del CRT (/ MDd)

Guarda le opzioni del linker, Progetto + Proprietà, Linker, Riga di comando. Nota come queste librerie non sono menzionate qui. Il linker rileva automaticamente quale / M switch è stato utilizzato dal compilatore e quale .lib deve essere collegato tramite una direttiva di commento #pragma. Un po ‘importante, potresti ottenere errori di link orribili e difficili da diagnosticare errori di runtime se c’è stata una mancata corrispondenza tra l’opzione / M e il .lib con cui ti colleghi.

Vedrai il messaggio di errore che hai citato quando viene detto al linker di collegarsi a msvcrt.lib e libcmt.lib. Che succederà se si collega il codice che è stato compilato con / MT con il codice che è stato collegato con / MD. Ci può essere solo una versione del CRT.

/ NODEFAULTLIB indica al linker di ignorare la direttiva di commento #pragma generata dal codice compilato / MT. Questo potrebbe funzionare, anche se una manciata di altri errori di linker non è rara. Cose come errno , che è un extern int nella versione statica CRT ma macro-ed a una funzione nella versione DLL. Molti altri come loro.

Bene, risolvi questo problema nel modo giusto, trova il file .obj o .lib che stai collegando che è stato compilato con l’opzione / M sbagliata. Se non hai idea, puoi trovarlo estrapolando i file .obj / .lib per “/ MT”

Btw: gli eseguibili di Windows (come version.dll) hanno la loro versione CRT per svolgere il loro lavoro. Si trova in c: \ windows \ system32, non è ansible utilizzarlo in modo affidabile per i propri programmi, le intestazioni CRT non sono disponibili da nessuna parte. La DLL CRT utilizzata dal programma ha un nome diverso (come msvcrt90.dll).

Significa che una delle dll dipendenti è compilata con una libreria run-time diversa.

Progetto -> Proprietà -> C / C ++ -> Generazione codice -> Libreria runtime

Passa sopra tutte le librerie e vedi che sono compilate allo stesso modo.

Ulteriori informazioni su questo errore in questo collegamento:

warning LNK4098: defaultlib “LIBCD” è in conflitto con l’uso di altre librerie

IMO questo link di Yochai Timmer era molto buono e pertinente ma doloroso da leggere. Ho scritto un riassunto.

Yochai, se hai mai letto questo, per favore vedi la nota alla fine.


Per il post originale leggi: avviso LNK4098: defaultlib “LIBCD” in conflitto con l’uso di altre librerie

Errore

LINK: avviso LNK4098: defaultlib “LIBCD” è in conflitto con l’uso di altre librerie; usa / NODEFAULTLIB: libreria

Senso

una parte del sistema è stata compilata per utilizzare una singola libreria standard (libc) con informazioni di debug (libcd) che è collegata staticamente

mentre un’altra parte del sistema è stata compilata per utilizzare una libreria standard multi-thread senza informazioni di debug che risiedono in una DLL e utilizza il collegamento dinamico

Come risolvere

  • Ignora l’avviso, dopotutto è solo un avvertimento. Tuttavia, il tuo programma ora contiene più istanze delle stesse funzioni.

  • Utilizzare l’opzione linker / NODEFAULTLIB: lib. Questa non è una soluzione completa, anche se puoi colbind il tuo programma in questo modo stai ignorando un segnale di avvertenza: il codice è stato compilato per diversi ambienti, alcuni del tuo codice potrebbero essere compilati per un singolo modello filettato mentre altro codice è multi-thread.

  • […] scorri attraverso tutte le tue librerie e assicurati che abbiano le impostazioni di collegamento corrette

In quest’ultimo caso, come menzionato nel post originale, possono sorgere due problemi comuni:

  • Hai una libreria di terze parti che è collegata in modo diverso alla tua applicazione.

  • Hai altre direttive incorporate nel tuo codice: normalmente questo è l’MFC. Se tutti i moduli del sistema si collegano con MFC, tutti i moduli devono essere collegati nominalmente alla stessa versione di MFC.

In questi casi, assicurarsi di comprendere il problema e decidere tra le soluzioni.


Nota: volevo includere il riassunto del collegamento di Yochai Timmer nella sua risposta, ma dal momento che alcune persone hanno problemi a rivedere le modifiche correttamente, ho dovuto scriverlo in una risposta separata. scusate

Ottengo questo ogni volta che voglio creare un’applicazione in VC ++.

Fare clic con il tasto destro del mouse sul progetto, selezionare Proprietà, quindi in “Proprietà di configurazione | C / C ++ | Generazione codice ‘, selezionare “Debug multithreading (/ MTd)” per la configurazione di debug.

Nota che questo non cambia le impostazioni per la tua configurazione di Release: dovrai andare nella stessa posizione e selezionare “Multi-threaded (/ MT)” per Release.

Fare clic con il tasto destro del mouse sul progetto, selezionare Proprietà, quindi sotto “Proprietà di configurazione | Linker | Input | Ignora la libreria specifica e scrivi msvcrtd.lib