การแก้ไข LNK4098: defaultlib 'MSVCRT' ขัดแย้งกับ


216

คำเตือนนี้:

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

เป็นคำเตือนทั่วไปใน Visual Studio ฉันต้องการที่จะเข้าใจเหตุผลที่แน่นอนสำหรับมันและวิธีการที่ถูกต้อง (ถ้าทั้งหมด) เพื่อจัดการกับมัน

/MDdนี้เกิดขึ้นในการแก้ปัญหาการสร้างรวบรวมกับ โครงการเชื่อมโยงกับสิ่งที่ชอบหน้าต่างVersion.dllและที่ตัวเองเชื่อมโยงกับpdh.dll MSVCRT.dllเห็นได้ชัดว่าฉันไม่มีเวอร์ชันแก้ไขข้อบกพร่องเหล่านี้และไม่สามารถรวบรวมได้

ดังนั้นฉันเพิ่ม/NODEFAULTLIB:MSVCRTเข้าไปในบรรทัดคำสั่งของ linker และมันก็ลบคำเตือนออก แต่สิ่งนี้ทำอะไรได้จริง? และทำไมมันจำเป็น?

คำตอบ:


273

ไลบรารีลิงก์ CRT มีอยู่ 4 เวอร์ชันใน vc \ lib:

  • libcmt.lib: ไลบรารีลิงก์ CRT แบบคงที่สำหรับ release build (/ MT)
  • libcmtd.lib: ไลบรารีลิงก์ CRT แบบคงที่สำหรับการสร้างข้อบกพร่อง (/ MTd)
  • msvcrt.lib: นำเข้าไลบรารีสำหรับรุ่น DLL ของ CRT (/ MD)
  • msvcrtd.lib: นำเข้าไลบรารีสำหรับรุ่น debug DLL ของ CRT (/ MDd)

ดูตัวเลือก linker, โครงการ + คุณสมบัติ, Linker, Command Line โปรดสังเกตว่าไลบรารีเหล่านี้ไม่ได้กล่าวถึงที่นี่ ตัวลิงก์จะระบุว่าสวิตช์ / M ถูกใช้โดยคอมไพเลอร์อย่างไรและควรจะเชื่อมโยงกับ. lib ผ่านทางคำสั่ง #pragma สำคัญคุณจะได้รับข้อผิดพลาดในการเชื่อมโยงที่น่ากลัวและยากที่จะวินิจฉัยข้อผิดพลาดรันไทม์หากมีความไม่ตรงกันระหว่างตัวเลือก / M และ. lib ที่คุณเชื่อมโยงด้วย

คุณจะเห็นข้อความแสดงข้อผิดพลาดที่คุณยกมาเมื่อมีการบอกให้ linker เชื่อมโยงไปยัง msvcrt.lib และ libcmt.lib ซึ่งจะเกิดขึ้นหากคุณเชื่อมโยงรหัสที่คอมไพล์ด้วย / MT ด้วยรหัสที่เชื่อมโยงกับ / MD สามารถมี CRT ได้เพียงเวอร์ชันเดียวเท่านั้น

/ NODEFAULTLIB บอกให้ linker ละเว้นคำสั่ง #pragma comment ที่สร้างขึ้นจากโค้ดที่คอมไพล์แล้ว / MT สิ่งนี้อาจใช้งานได้แม้ว่าข้อผิดพลาดตัวเชื่อมโยงอื่น ๆ จะไม่ผิดปกติ สิ่งที่ชอบerrnoซึ่งเป็น int ภายนอกในรุ่น CRT คงที่ แต่แมโคร -ed ไปยังฟังก์ชั่นในรุ่น DLL คนอื่น ๆ เช่นนั้น

แก้ไขปัญหานี้ให้ถูกต้องค้นหาไฟล์. obj หรือ. lib ที่คุณกำลังเชื่อมโยงซึ่งถูกคอมไพล์ด้วยตัวเลือกผิด / M หากคุณไม่มีเงื่อนงำคุณสามารถค้นหาได้โดยการ grepping ไฟล์. obj / .lib สำหรับ "/ MT"

Btw: ไฟล์ปฏิบัติการ Windows (เช่น version.dll) มีรุ่น CRT ของตัวเองเพื่อทำงานให้เสร็จ มันตั้งอยู่ใน c: \ windows \ system32 คุณไม่สามารถใช้งานได้อย่างน่าเชื่อถือสำหรับโปรแกรมของคุณเองส่วนหัว CRT ไม่สามารถใช้ได้ทุกที่ CRT DLL ที่ใช้โดยโปรแกรมของคุณมีชื่อแตกต่างกัน (เช่น msvcrt90.dll)


2
ขอบคุณโพสต์นี้ฉันยังคงค้นหา. lib ที่ยังคงใช้ / MDd และในที่สุดฉันก็พบ! ขอบคุณ +1
ceztko

64
เคล็ดลับที่ฉันเพิ่งเรียนรู้ที่จะติดตามไลบรารีที่ดึงเข้ามาในไลบรารี CRT ที่ผิดคือเพิ่ม/verbose:libตัวเลือกลิงเกอร์เพิ่มเติม มันแสดงให้เห็นลำดับที่ไฟล์ .LIB โหลดในช่วยให้คุณสามารถที่จะดูว่าคนที่ไม่ถูกต้องถูกดึงใน.
obmarg

1
ฮันส์มันอันตรายแค่ไหน? หากเราไม่สามารถแก้ไขได้ (เราได้รับ lib รวบรวมจากผู้ขายของเรา) ผลกระทบอะไรที่เราอาจเผชิญ
Ivan Nikitin

3
ฉันพบความคิดเห็น @obmarg 'มีประโยชน์ แต่ก็ยังไม่แน่ใจว่าจะใช้เอาต์พุต verbose อย่างไรจนกระทั่งพบmsdn.microsoft.com/en-us/library/aa267384(v=vs.60).aspxซึ่งกล่าวว่าเอาต์พุต verbose จะ บอกไลบรารีรันไทม์ทั้งหมดที่เกี่ยวข้องกับปัญหาลิงก์ให้คุณทราบ คุณยังคงต้องคิดออกว่าลิงค์อินพุตใดที่ได้รับการรวบรวมกับ Runtime Library ที่ขัดแย้งกัน
buzz3791

4
@ buzz3791 ใช้ / verbose แทน / verbose: lib ข้อมูลที่แสดงรวมถึงกระบวนการค้นหาไลบรารีและแสดงรายการแต่ละไลบรารีและชื่อวัตถุ (พร้อมเส้นทางแบบเต็ม) สัญลักษณ์ที่ได้รับการแก้ไขจากไลบรารีและรายการวัตถุที่อ้างอิงสัญลักษณ์ / verbose สามารถแสดงข้อมูลทั้งหมดที่คุณต้องการในการค้นหาคนร้ายที่ทำให้เกิดข้อขัดแย้ง
Yang Kui

46

หมายความว่าหนึ่งใน DLLs ที่ต้องพึ่งพานั้นถูกคอมไพล์ด้วยไลบรารีรันไทม์อื่น

โครงการ -> คุณสมบัติ -> C / C ++ -> การสร้างรหัส -> Runtime Library

ไปห้องสมุดทั้งหมดและดูว่าพวกเขาจะรวบรวมในลักษณะเดียวกัน

เพิ่มเติมเกี่ยวกับข้อผิดพลาดนี้ในลิงค์นี้:

คำเตือน LNK4098: defaultlib "LIBCD" ขัดแย้งกับการใช้ libs อื่น ๆ


นั่นคือสาเหตุของข้อผิดพลาด! ขอบคุณสำหรับทิป.
rkachach

1
นี่คือคำตอบที่ดีที่สุดสำหรับโปรแกรมเมอร์ที่มีประสบการณ์น้อยกว่า
meolic

32

IMO ลิงค์นี้จากYochai Timmerดีมากและมีความเกี่ยวข้อง แต่เจ็บปวดในการอ่าน ฉันเขียนบทสรุป

Yochai ถ้าคุณเคยอ่านสิ่งนี้โปรดดูหมายเหตุในตอนท้าย


สำหรับโพสต์ดั้งเดิมอ่าน: คำเตือน LNK4098: defaultlib "LIBCD" ขัดแย้งกับการใช้ libs อื่น ๆ

ความผิดพลาด

ลิงค์: คำเตือน LNK4098: defaultlib "LIBCD" ขัดแย้งกับการใช้ libs อื่น ๆ ; use / NODEFAULTLIB: library

ความหมาย

ส่วนหนึ่งของระบบถูกคอมไพล์เพื่อใช้ไลบรารีมาตรฐานเธรดเดียว (libc) พร้อมกับข้อมูลการดีบัก (libcd) ซึ่งถูกลิงก์แบบสแตติก

ในขณะที่อีกส่วนหนึ่งของระบบได้รับการคอมไพล์เพื่อใช้ไลบรารีมาตรฐานแบบมัลติเธรดโดยไม่มีข้อมูลการดีบักซึ่งอยู่ใน DLL และใช้การเชื่อมโยงแบบไดนามิก

วิธีแก้ไข

  • ละเว้นคำเตือนหลังจากทั้งหมดเป็นเพียงคำเตือน อย่างไรก็ตามโปรแกรมของคุณมีฟังก์ชันเดียวกันหลายอินสแตนซ์

  • ใช้ตัวเลือก linker / NODEFAULTLIB: lib นี่ไม่ใช่วิธีการแก้ปัญหาที่สมบูรณ์แม้ว่าคุณจะสามารถทำให้โปรแกรมเชื่อมโยงในลักษณะที่คุณไม่สนใจสัญญาณเตือน: รหัสได้รับการรวบรวมสำหรับสภาพแวดล้อมที่แตกต่างกันรหัสของคุณบางส่วนอาจถูกรวบรวมสำหรับรุ่นเธรดเดียวในขณะที่รหัสอื่นคือ แบบมัลติเธรด

  • [... ] ติดตามทุกห้องสมุดของคุณและตรวจสอบให้แน่ใจว่าพวกเขามีการตั้งค่าลิงค์ที่ถูกต้อง

ในหลังตามที่กล่าวไว้ในโพสต์ต้นฉบับปัญหาทั่วไปที่สองสามารถเกิดขึ้น:

  • คุณมีห้องสมุดบุคคลที่สามซึ่งเชื่อมโยงกับแอปพลิเคชันของคุณแตกต่างกัน

  • คุณมีคำสั่งอื่น ๆ ที่ฝังอยู่ในรหัสของคุณ: โดยปกตินี่คือ MFC หากโมดูลใด ๆ ในระบบเชื่อมโยงกับ MFC โมดูลทั้งหมดของคุณจะต้องเชื่อมโยงกับ MFC รุ่นเดียวกัน

สำหรับกรณีเหล่านี้ให้แน่ใจว่าคุณเข้าใจปัญหาและตัดสินใจในการแก้ปัญหา


หมายเหตุ: ฉันต้องการรวมบทสรุปของลิงค์ของ Yochai Timmer ไว้ในคำตอบของเขาเอง แต่เนื่องจากบางคนมีปัญหาในการตรวจสอบการแก้ไขอย่างถูกต้องฉันต้องเขียนในคำตอบแยกต่างหาก ขอโทษ


7

ฉันได้รับสิ่งนี้ทุกครั้งที่ฉันต้องการสร้างแอปพลิเคชันใน VC ++

คลิกขวาที่โครงการแล้วเลือกคุณสมบัติจากนั้นภายใต้ 'คุณสมบัติการกำหนดค่า | C / C ++ | การสร้างรหัส 'เลือก "ดีบักแบบหลายเธรด (/ MTd)" สำหรับการกำหนดค่าการดีบัก

โปรดทราบว่านี่จะไม่เปลี่ยนการตั้งค่าสำหรับการกำหนดค่า Release ของคุณ - คุณจะต้องไปที่ตำแหน่งเดียวกันและเลือก "Multi-threaded (/ MT)" สำหรับ Release


4

คลิกขวาที่โครงการแล้วเลือกคุณสมบัติจากนั้นภายใต้ 'คุณสมบัติการกำหนดค่า | Linker | อินพุต | ละเว้นไลบรารีเฉพาะและเขียน msvcrtd.lib

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.