Resolvendo conflitos LNK4098: defaultlib ‘MSVCRT’ com

Este aviso:

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

é um aviso bastante comum no Visual Studio. Eu gostaria de entender a razão exata para isso e o caminho certo (se for o caso) para lidar com isso.

Isso vem em uma compilation de debugging, compilada com /MDd . O projeto está ligado a coisas como o windows Version.dll e pdh.dll que se ligam com MSVCRT.dll . Obviamente, não tenho as versões de debugging e não posso compilá-las.

Então eu adicionei /NODEFAULTLIB:MSVCRT à linha de comando do linker e ele realmente removeu o aviso. Mas o que isso realmente faz? E por que isso é necessário?

Existem 4 versões das bibliotecas de links CRT presentes em vc \ lib:

  • libcmt.lib: biblioteca de links CRT estática para uma compilation de release (/ MT)
  • libcmtd.lib: biblioteca de links CRT estática para uma compilation de debugging (/ MTd)
  • msvcrt.lib: biblioteca de importação para a versão de DLL de liberação do CRT (/ MD)
  • msvcrtd.lib: biblioteca de importação para a versão de DLL de debugging do CRT (/ MDd)

Veja as opções do vinculador, Project + Properties, Linker, Command Line. Observe como essas bibliotecas não são mencionadas aqui. O vinculador descobre automaticamente qual opção / M foi usada pelo compilador e qual .lib deve ser vinculado por meio de uma diretiva de comentário #pragma. Meio importante, você teria erros de link horríveis e seria difícil diagnosticar erros de tempo de execução se houvesse uma incompatibilidade entre a opção / M e o .lib que você vincula.

Você verá a mensagem de erro que você citou quando o vinculador é informado para vincular a msvcrt.lib e libcmt.lib. O que acontecerá se você vincular o código que foi compilado com / MT com código vinculado a / MD. Pode haver apenas uma versão do CRT.

/ NODEFAULTLIB informa ao vinculador para ignorar a diretiva de comentário # pragma que foi gerada a partir do código compilado / MT. Isso pode funcionar, embora uma série de outros erros de vinculação não seja incomum. Coisas como errno , que é um extern int na versão CRT estática, mas macro-ed para uma function na versão DLL. Muitos outros gostam disso.

Bem, corrija este problema do jeito certo, encontre o arquivo .obj ou .lib que você está vinculando e que foi compilado com a opção errada / M. Se você não tem nenhuma pista, você pode encontrá-lo usando os arquivos .obj / .lib para “/ MT”

Btw: os executáveis ​​do Windows (como version.dll) têm sua própria versão CRT para realizar seu trabalho. Ele está localizado em c: \ windows \ system32, você não pode usá-lo de forma confiável para seus próprios programas, seus headers CRT não estão disponíveis em nenhum lugar. A DLL de CRT usada pelo seu programa tem um nome diferente (como msvcrt90.dll).

Isso significa que uma das dlls dependentes é compilada com uma biblioteca de tempo de execução diferente.

Projeto -> Propriedades -> C / C ++ -> Geração de Código -> Biblioteca de Tempo de Execução

Revise todas as bibliotecas e veja que elas são compiladas da mesma maneira.

Mais sobre este erro neste link:

aviso LNK4098: defaultlib “LIBCD” está em conflito com o uso de outras libs

IMO este link de Yochai Timmer foi muito bom e relevante, mas doloroso de ler. Eu escrevi um resumo.

Yochai, se você já leu isso, por favor, veja a nota no final.


Para o post original, leia: aviso LNK4098: defaultlib “LIBCD” está em conflito com o uso de outras libs

Erro

LINK: aviso LNK4098: defaultlib “LIBCD” está em conflito com o uso de outras libs; use / NODEFAULTLIB: biblioteca

Significado

uma parte do sistema foi compilada para usar uma biblioteca padrão única (libc) com informações de debugging (libcd) que está estaticamente vinculada

enquanto outra parte do sistema foi compilada para usar uma biblioteca padrão multi-threaded sem informações de debugging que residem em uma DLL e usam links dynamics

Como resolver

  • Ignore o aviso, afinal é apenas um aviso. No entanto, seu programa agora contém várias instâncias das mesmas funções.

  • Use a opção de vinculador / NODEFAULTLIB: lib. Esta não é uma solução completa, mesmo se você puder fazer o seu programa linkar desta forma você está ignorando um sinal de aviso: o código foi compilado para ambientes diferentes, alguns de seu código podem ser compilados para um único modelo encadeado enquanto outro código é multi-threaded.

  • […] vasculhar todas as suas bibliotecas e garantir que elas tenham as configurações corretas de links

Neste último, como mencionado no post original, dois problemas comuns podem surgir:

  • Você tem uma biblioteca de terceiros que está vinculada de maneira diferente à sua inscrição.

  • Você tem outras diretivas incorporadas em seu código: normalmente, este é o MFC. Se algum dos módulos do seu sistema estiver vinculado ao MFC, todos os seus módulos devem estar vinculados nominalmente à mesma versão do MFC.

Para esses casos, certifique-se de entender o problema e decidir entre as soluções.


Nota: Eu queria include esse resumo do link de Yochai Timmer em sua própria resposta, mas como algumas pessoas têm problemas para revisar as edições corretamente, eu tive que escrevê-lo em uma resposta separada. Desculpa

Eu recebo isso toda vez que quero criar um aplicativo no VC ++.

Clique com o botão direito do mouse no projeto, selecione Propriedades e, em seguida, em Propriedades de configuração | C / C ++ | Geração de código ‘, selecione “Debug multithread (/ MTd)” para configuração de debugging.

Observe que isso não altera a configuração da sua configuração de lançamento – você precisará ir para o mesmo local e selecionar “Multi-threaded (/ MT)” para Release.

Clique com o botão direito do mouse no projeto, selecione Propriedades e, em seguida, em Propriedades de configuração | Linker | Entrada | Ignore a biblioteca específica e escreva msvcrtd.lib