LNK4098 çözümleniyor: defaultlib 'MSVCRT' ile çakışıyor


216

Bu uyarı:

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

Visual Studio'da oldukça yaygın bir uyarıdır. Bunun tam nedenini ve bununla başa çıkmak için doğru yolu (eğer varsa) anlamak istiyorum.

Bu, derlenmiş bir hata ayıklama derlemesinde ortaya çıkar /MDd. Proje, pencereler gibi Version.dllve pdh.dllkendileriyle bağlantı kuran şeylerle bağlantılıdır MSVCRT.dll. Açıkçası, bunların hata ayıklama sürümlerine sahip değilim ve bunları derleyemiyorum.

Bu yüzden /NODEFAULTLIB:MSVCRTlinker komut satırına ekledim ve aslında uyarıyı kaldırdı. Ama bu aslında ne yapıyor? Ve neden gerekli?

Yanıtlar:


273

Vc \ lib dosyasında bulunan CRT bağlantı kitaplıklarının 4 sürümü vardır:

  • libcmt.lib: sürüm derlemesi (/ MT) için statik CRT bağlantı kitaplığı
  • libcmtd.lib: Hata ayıklama derlemesi için statik CRT bağlantı kitaplığı (/ MTd)
  • msvcrt.lib: CRT'nin (/ MD) sürüm DLL sürümü için içe aktarma kitaplığı
  • msvcrtd.lib: CRT (/ MDd) hata ayıklama DLL sürümü için alma kitaplığı

Bağlayıcı seçeneklerine, Proje + Özellikleri, Bağlayıcı, Komut Satırı'na bakın. Bu kütüphanelerin burada nasıl bahsedilmediğine dikkat edin. Bağlayıcı, derleyici tarafından hangi / M anahtarının kullanıldığını ve # .pragma açıklama yönergesi ile hangi .lib'in bağlanması gerektiğini otomatik olarak bulur. Önemli olarak, / M seçeneği ile bağlandığınız .lib arasında bir uyumsuzluk olsaydı korkunç bağlantı hataları ve çalışma zamanı hatalarını teşhis etmek zor olurdu.

Sen bağlayıcı MSVCRT.LIB bağlantısını hem anlattı durumdayken alıntı hata mesajı görürsünüz ve LIBCMT.LIB. / MT ile derlenen kodu / MD ile bağlantılı kodla bağlarsanız bu gerçekleşir. CRT'nin yalnızca bir sürümü olabilir.

/ NODEFAULTLIB, bağlayıcıya / MT derlenmiş kodundan oluşturulan #pragma comment yönergesini yoksaymasını söyler. Diğer linker hatalarının bir kısmı nadir olmasa da bu işe yarayabilir. Errno gibi şeyler , statik CRT sürümünde bir extern int olan ancak DLL sürümünde bir işleve makro olarak düzenlenmiş. Diğer pek çok kişi böyle.

Peki, bu sorunu doğru şekilde düzeltin, bağladığınız .obj veya .lib dosyasını yanlış / M seçeneğiyle derleyin. Eğer bir ipucunuz yoksa "/ MT" için .obj / .lib dosyalarını açarak bulabilirsiniz.

Btw: Windows yürütülebilir dosyaları (version.dll gibi) işlerini yapmak için kendi CRT sürümlerine sahiptir. C: \ windows \ system32 içinde bulunur, kendi programlarınız için güvenilir bir şekilde kullanamazsınız, CRT başlıkları hiçbir yerde mevcut değildir. Programınız tarafından kullanılan CRT DLL farklı bir ada sahip (msvcrt90.dll gibi).


2
Bu yazı sayesinde, hala / MDd kullanan bir .lib aramaya devam ettim ve sonunda bir tane buldum! Teşekkürler, +1
ceztko

64
Yanlış CRT kitaplıklarını çeken kitaplıkları izlemeyi öğrendiğim bir püf /verbose:libnoktası, ek bağlayıcı seçeneklerine eklemektir . .Lib dosyalarının yüklenme sırasını gösterir, yanlış
dosyanın

1
Hans, ne kadar tehlikeli? Bunu düzeltemezsek (tedarikçimizden derlenmiş bir lib alırız), ne gibi sonuçlarla karşılaşabiliriz?
Ivan Nikitin

3
Ben @obmarg' comment yararlı buldum ama hala bulana kadar çıktı ayrıntılı nasıl kullanılacağını emin değildi msdn.microsoft.com/en-us/library/aa267384(v=vs.60).aspx ayrıntılı çıktı irade diyor ki yalnızca bağlantı sorunuyla ilgili tüm çalışma zamanı kitaplıklarını söyler. Daha sonra, çakışan Çalışma Zamanı Kitaplığı ile hangi bağlantı girişinin derlendiğini bulmanız gerekir.
buzz3791

4
@ buzz3791 / verbose: lib yerine / verbose kullanın. Görüntülenen bilgiler kütüphane arama işlemini içerir ve her kütüphane ve nesne adını (tam yolla), kütüphaneden çözülen sembolü ve sembole başvuran nesnelerin bir listesini listeler. / verbose, çakışmalara neden olan kötü adamı bulmak için ihtiyacınız olan tüm bilgileri görüntüleyebilir.
Yang Kui

46

Bağımlı dll'lerden birinin farklı bir çalışma zamanı kitaplığıyla derlendiği anlamına gelir .

Proje -> Özellikler -> C / C ++ -> Kod Üretimi -> Çalışma Zamanı Kütüphanesi

Tüm kütüphaneleri gözden geçirin ve aynı şekilde derlendiklerini görün.

Bu bağlantıdaki bu hata hakkında daha fazla bilgi:

LNK4098 uyarısı: defaultlib "LIBCD" diğer kütüphanelerin kullanımıyla çakışıyor


Hatanın nedeni buydu! Bahşiş için teşekkürler.
rkachach

1
Bu daha az deneyimli programcılar için en iyi cevaptır.
meolik

32

IMO bu bağlantıyı gelen Yochai Timmer okumak çok iyi ve alakalı ama acı oldu. Bir özet yazdım.

Yochai, daha önce okuduysanız, lütfen sondaki nota bakın.


Orijinal yazı için okuyun: LNK4098 uyarısı: defaultlib "LIBCD" diğer kütüphanelerin kullanımıyla çakışıyor

Hata

LINK: uyarı LNK4098: defaultlib "LIBCD" diğer kütüphanelerin kullanımıyla çakışıyor; use / NODEFAULTLIB: kütüphane

anlam

sistemin bir kısmı, statik olarak bağlı hata ayıklama bilgileri (libcd) içeren tek iş parçacıklı standart (libc) kitaplığı kullanmak üzere derlendi

sistemin başka bir parçası, bir DLL dosyasında bulunan ve dinamik bağlantı kullanan hata ayıklama bilgileri olmadan çok iş parçacıklı standart kitaplık kullanmak üzere derlendi

Çözüm

  • Uyarıyı görmezden gelin, sonuçta sadece bir uyarıdır. Ancak, programınız şimdi aynı işlevlerin birden çok örneğini içermektedir.

  • / NODEFAULTLIB: lib bağlayıcı seçeneğini kullanın. Bu, bir uyarı işaretini görmezden geldiğinizde programınızı bu şekilde bağlayabilmenize rağmen tam bir çözüm değildir: kod farklı ortamlar için derlenmiştir, kodunuzdan bazıları diğer bir kod ise tek bir dişli model için derlenebilir çoklu parçacıklı.

  • [...] tüm kütüphanelerinizde dolaşın ve doğru bağlantı ayarlarına sahip olduklarından emin olun

İkincisinde, orijinal gönderide belirtildiği gibi, iki yaygın sorun ortaya çıkabilir:

  • Uygulamanızla farklı şekilde bağlantılı bir üçüncü taraf kütüphaneniz var.

  • Kodunuza gömülü başka yönergeler var: normalde bu MFC'dir. Sisteminizdeki herhangi bir modül MFC'ye bağlanıyorsa, tüm modüllerin nominal olarak aynı MFC sürümüne bağlanmalıdır.

Bu durumlar için, sorunu anladığınızdan emin olun ve çözümler arasında karar verin.


Not: Yochai Timmer'ın bağlantısının özetini kendi cevabına dahil etmek istedim, ancak bazı insanlar düzenlemeleri düzgün bir şekilde gözden geçirmekte zorlandığından, ayrı bir cevapta yazmak zorunda kaldım. Afedersiniz


7

VC ++ 'da bir uygulama oluşturmak istediğimde bunu alıyorum.

Projeyi sağ tıklatın, Özellikler'i seçin ve 'Yapılandırma özellikleri | C / C ++ | Kod Üretimi ', Hata Ayıklama yapılandırması için "Çok iş parçacıklı Hata Ayıklama (/ MTd)" seçeneğini belirleyin.

Bunun Sürüm yapılandırmanızın ayarını değiştirmediğini unutmayın - aynı konuma gitmeniz ve Sürüm için "Çok iş parçacıklı (/ MT)" seçeneğini seçmeniz gerekir.


4

Projeyi sağ tıklatın, Özellikler'i seçin ve 'Yapılandırma özellikleri | Bağlayıcı | Girdi | Belirli bir Kitaplığı yoksay ve msvcrtd.lib yaz

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.