Resolvendo LNK4098: defaultlib 'MSVCRT' entra em conflito com
216
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 o motivo exato e a maneira correta (se houver) de lidar com isso.
Isso aparece em uma compilação de depuração, compilada com /MDd. O projeto está vinculado a coisas como janelas Version.dlle às pdh.dllquais elas se vinculam MSVCRT.dll. Obviamente, eu não tenho as versões de depuração delas e não posso compilá-las.
Então eu adicionei /NODEFAULTLIB:MSVCRTà linha de comando do vinculador e ele realmente removeu o aviso. Mas o que isso realmente faz? E porque é necessário?
Existem 4 versões das bibliotecas de links CRT presentes em vc \ lib:
libcmt.lib: biblioteca estática de links CRT para uma compilação de versão (/ MT)
libcmtd.lib: biblioteca estática de links CRT para uma compilação de depuração (/ MTd)
msvcrt.lib: biblioteca de importação para a versão DLL do CRT (/ MD)
msvcrtd.lib: biblioteca de importação para a versão DLL de depuração do CRT (/ MDd)
Observe as opções do vinculador, Projeto + Propriedades, Vinculador, Linha de comando. 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ê obteria erros de link horríveis e difíceis de diagnosticar erros de tempo de execução se houvesse uma incompatibilidade entre a opção / M e o .lib ao qual você vincula.
Você verá a mensagem de erro que você citou quando o vinculador for solicitado a vincular ao msvcrt.lib e libcmt.lib. O que acontecerá se você vincular o código que foi compilado com / MT com o código que foi vinculado com / MD. Pode haver apenas uma versão do CRT.
/ NODEFAULTLIB diz 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 do vinculador não seja incomum. Coisas como errno , que é um int externo na versão estática do CRT, mas com macro para uma função na versão DLL. Muitos outros assim.
Bem, corrija esse problema da maneira certa, localize o arquivo .obj ou .lib que você está vinculando que foi compilado com a opção / M errada. Se você não tem idéia, poderá encontrá-lo preenchendo 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 com segurança em seus próprios programas, seus cabeçalhos CRT não estão disponíveis em nenhum lugar. A DLL CRT usada pelo seu programa tem um nome diferente (como msvcrt90.dll).
Graças a este post, continuei procurando um .lib que ainda estava usando o / MDd e finalmente encontrei um! Obrigado, +1
ceztko 9/11/11
64
Um truque que aprendi a rastrear bibliotecas que estão puxando as bibliotecas CRT erradas é adicionar /verbose:libàs opções adicionais do vinculador. Ele mostra a fim de que .lib são carregados, o que lhe permite ver onde a incorreta foi puxado.
obmarg
1
Hans, como é perigoso? Se não podemos corrigi-lo (obtemos uma lib compilada de nosso fornecedor), que consequências podemos enfrentar?
Ivan Nikitin
3
Eu achei o comentário do @obmarg útil, mas ainda não tinha certeza de como usar a saída detalhada até encontrar msdn.microsoft.com/en-us/library/aa267384(v=vs.60).aspx, que diz que a saída detalhada será informe apenas todas as bibliotecas de tempo de execução envolvidas no problema do link. Você ainda precisa descobrir qual entrada de link foi compilada com a Runtime Library conflitante.
precisa saber é o seguinte
4
@ buzz3791 use / verbose em vez de / verbose: lib. As informações exibidas incluem o processo de pesquisa da biblioteca e listam cada nome de biblioteca e objeto (com caminho completo), o símbolo sendo resolvido a partir da biblioteca e uma lista de objetos que fazem referência ao símbolo. / verbose pode exibir todas as informações necessárias para encontrar o bandido que causa os conflitos.
LINK: aviso LNK4098: defaultlib "LIBCD" entra em conflito com o uso de outras bibliotecas; use / NODEFAULTLIB: biblioteca
Significado
uma parte do sistema foi compilada para usar uma única biblioteca padrão encadeada (libc) com informações de depuração (libcd), que são vinculadas estaticamente
enquanto outra parte do sistema foi compilada para usar uma biblioteca padrão multiencadeada sem informações de depuração que residem em uma DLL e usam vínculo dinâmico
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 que você consiga vincular seu programa dessa maneira, você está ignorando um sinal de aviso: o código foi compilado para diferentes ambientes, parte do seu código pode ser compilado para um único modelo de encadeamento enquanto outro código é multiencadeado.
vasculhe todas as suas bibliotecas e garanta que elas tenham as configurações de link corretas
Neste último, como mencionado no post original, dois problemas comuns podem surgir:
Você tem uma biblioteca de terceiros que está vinculada diferentemente ao seu aplicativo.
Você tem outras diretivas incorporadas ao seu código: normalmente esse é o MFC. Se algum módulo do seu sistema estiver vinculado ao MFC, todos os módulos deverão vincular nominalmente à mesma versão do MFC.
Para esses casos, certifique-se de entender o problema e decidir entre as soluções.
Nota: Eu queria incluir 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, tive que escrevê-lo em uma resposta separada. Desculpe
Recebo isso toda vez que desejo criar um aplicativo no VC ++.
Clique com o botão direito do mouse no projeto, selecione Propriedades e, em 'Propriedades da configuração | C / C ++ Code Generation ', selecione "Multi-threaded Debug (/ MTd)" para configuração de Debug.
Observe que isso não altera a configuração da sua versão do Release - você precisará ir para o mesmo local e selecionar "Multi-threaded (/ MT)" para o Release.
Clique com o botão direito do mouse no projeto, selecione Propriedades e, em 'Propriedades da configuração | Linker Entrada | Ignore a biblioteca específica e escreva msvcrtd.lib
/verbose:lib
às opções adicionais do vinculador. Ele mostra a fim de que .lib são carregados, o que lhe permite ver onde a incorreta foi puxado.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
Examine todas as bibliotecas e veja se elas são compiladas da mesma maneira.
Mais sobre este erro neste link:
aviso LNK4098: defaultlib "LIBCD" entra em conflito com o uso de outras bibliotecas
fonte
OMI este link de Yochai Timmer foi muito bom e relevante, mas doloroso de ler. Eu escrevi um resumo
Yochai, se você já leu isso, consulte a nota no final.
Para a postagem original, leia: aviso LNK4098: defaultlib "LIBCD" entra em conflito com o uso de outras bibliotecas
Erro
Significado
Como resolver
Neste último, como mencionado no post original, dois problemas comuns podem surgir:
Para esses casos, certifique-se de entender o problema e decidir entre as soluções.
Nota: Eu queria incluir 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, tive que escrevê-lo em uma resposta separada. Desculpe
fonte
Recebo isso toda vez que desejo criar um aplicativo no VC ++.
Clique com o botão direito do mouse no projeto, selecione Propriedades e, em 'Propriedades da configuração | C / C ++ Code Generation ', selecione "Multi-threaded Debug (/ MTd)" para configuração de Debug.
Observe que isso não altera a configuração da sua versão do Release - você precisará ir para o mesmo local e selecionar "Multi-threaded (/ MT)" para o Release.
fonte
Clique com o botão direito do mouse no projeto, selecione Propriedades e, em 'Propriedades da configuração | Linker Entrada | Ignore a biblioteca específica e escreva msvcrtd.lib
fonte