Giải quyết LNK4098: defaultlib 'MSVCRT' xung đột với


216

Cảnh báo này:

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

là một cảnh báo khá phổ biến trong Visual Studio. Tôi muốn hiểu lý do chính xác cho nó và cách đúng (nếu có) để xử lý nó.

Điều này xuất hiện trong một bản dựng gỡ lỗi, được biên dịch với /MDd. Dự án được liên kết với những thứ như cửa sổ Version.dllpdh.dllchính chúng liên kết với MSVCRT.dll. Rõ ràng, tôi không có các phiên bản gỡ lỗi của chúng và không thể biên dịch chúng.

Vì vậy, tôi đã thêm vào /NODEFAULTLIB:MSVCRTdòng lệnh liên kết và nó thực sự đã loại bỏ cảnh báo. Nhưng điều này thực sự làm gì? Và tại sao nó lại cần thiết?

Câu trả lời:


273

Có 4 phiên bản của thư viện liên kết CRT có trong vc \ lib:

  • libcmt.lib: thư viện liên kết CRT tĩnh cho bản dựng phát hành (/ MT)
  • libcmtd.lib: thư viện liên kết CRT tĩnh cho bản dựng gỡ lỗi (/ MTd)
  • msvcrt.lib: nhập thư viện cho phiên bản DLL phát hành của CRT (/ MD)
  • msvcrtd.lib: nhập thư viện cho phiên bản DLL gỡ lỗi của CRT (/ MDd)

Nhìn vào các tùy chọn liên kết, Project + Properties, Linker, Command Line. Lưu ý làm thế nào các thư viện không được đề cập ở đây. Trình liên kết tự động tìm ra công tắc / M nào được trình biên dịch sử dụng và .lib nên được liên kết thông qua chỉ thị nhận xét #pragma. Điều quan trọng là, bạn sẽ gặp lỗi liên kết khủng khiếp và khó chẩn đoán lỗi thời gian chạy nếu có sự không khớp giữa tùy chọn / M và .lib mà bạn liên kết.

Bạn sẽ thấy thông báo lỗi bạn đã trích dẫn khi trình liên kết được yêu cầu cả hai liên kết đến msvcrt.lib libcmt.lib. Điều này sẽ xảy ra nếu bạn liên kết mã được biên dịch với / MT với mã được liên kết với / MD. Chỉ có thể có một phiên bản CRT.

/ NODEFAULTLIB yêu cầu người liên kết bỏ qua chỉ thị nhận xét #pragma được tạo từ mã được biên dịch / MT. Điều này có thể hoạt động, mặc dù một loạt các lỗi liên kết khác không phải là hiếm. Những thứ như errno , là một extern int trong phiên bản CRT tĩnh nhưng macro-ed thành một chức năng trong phiên bản DLL. Nhiều người khác thích điều đó.

Chà, khắc phục vấn đề này đúng cách, tìm tệp .obj hoặc .lib mà bạn đang liên kết được biên dịch với tùy chọn sai / M. Nếu bạn không có đầu mối thì bạn có thể tìm thấy nó bằng cách lấy các tệp .obj / .lib cho "/ MT"

Btw: các tệp thực thi Windows (như version.dll) có phiên bản CRT riêng để hoàn thành công việc của họ. Nó nằm trong c: \ windows \ system32, bạn không thể sử dụng nó một cách đáng tin cậy cho các chương trình của riêng bạn, các tiêu đề CRT của nó không có sẵn ở bất cứ đâu. DLL CRT được sử dụng bởi chương trình của bạn có một tên khác (như msvcrt90.dll).


2
Nhờ bài đăng này, tôi tiếp tục tìm kiếm một .lib vẫn đang sử dụng / MDd và cuối cùng tôi đã tìm thấy một! Cảm ơn, +1
ceztko

64
Một mẹo tôi vừa học được để theo dõi các thư viện đang kéo các thư viện CRT sai là thêm /verbose:libvào các tùy chọn liên kết bổ sung. Nó hiển thị thứ tự các tệp .lib được tải vào, cho phép bạn xem vị trí không chính xác được kéo vào.
obmarg

1
Hans, nó nguy hiểm thế nào? Nếu chúng tôi không thể sửa nó (chúng tôi nhận được một lib được biên dịch từ nhà cung cấp của chúng tôi), hậu quả chúng ta có thể gặp phải là gì?
Ivan Nikitin

3
Tôi thấy nhận xét của @obmarg rất hữu ích nhưng vẫn không chắc chắn cách sử dụng đầu ra dài dòng cho đến khi tôi tìm thấy msdn.microsoft.com/en-us/l Library / aa267384 (v = vs.60) .aspx cho biết đầu ra dài dòng sẽ chỉ cho bạn biết tất cả các thư viện thời gian chạy liên quan đến vấn đề liên kết. Sau đó, bạn vẫn phải tìm ra đầu vào liên kết nào đã được biên dịch với Thư viện Thời gian xung đột.
buzz3791

4
@ buzz3791 sử dụng / verbose thay vì / verbose: lib. Thông tin được hiển thị bao gồm quá trình tìm kiếm thư viện và liệt kê từng thư viện và tên đối tượng (có đường dẫn đầy đủ), biểu tượng được giải quyết từ thư viện và danh sách các đối tượng tham chiếu biểu tượng. / verbose có thể hiển thị tất cả thông tin bạn cần để tìm kẻ xấu gây ra xung đột.
Yang Kui

46

Nó có nghĩa là một trong những dll phụ thuộc được biên dịch với một thư viện thời gian chạy khác nhau .

Dự án -> Thuộc tính -> C / C ++ -> Tạo mã -> Thư viện thời gian chạy

Đi qua tất cả các thư viện và thấy rằng chúng được biên dịch theo cùng một cách.

Thông tin thêm về lỗi này trong liên kết này:

cảnh báo LNK4098: defaultlib "LIBCD" xung đột với việc sử dụng các lib khác


Đó là lý do của lỗi! Cảm ơn vì tiền hỗ trợ.
rkachach

1
Đây là câu trả lời tốt nhất cho các lập trình viên ít kinh nghiệm.
meolic

32

IMO liên kết này từ Yochai Timmer là rất tốt và có liên quan nhưng đau đớn để đọc. Tôi đã viết một bản tóm tắt.

Yochai, nếu bạn đã từng đọc nó, xin vui lòng xem ghi chú ở cuối.


Đối với bài đăng gốc, hãy đọc: cảnh báo LNK4098: defaultlib "LIBCD" xung đột với việc sử dụng các lib khác

lỗi

LINK: cảnh báo LNK4098: defaultlib "LIBCD" xung đột với việc sử dụng các lib khác; sử dụng / NODEFAULTLIB: thư viện

Ý nghĩa

một phần của hệ thống đã được biên dịch để sử dụng một thư viện tiêu chuẩn (libc) đơn luồng với thông tin gỡ lỗi (libcd) được liên kết tĩnh

trong khi một phần khác của hệ thống được biên dịch để sử dụng thư viện chuẩn đa luồng mà không có thông tin gỡ lỗi nằm trong DLL và sử dụng liên kết động

Cách giải quyết

  • Bỏ qua cảnh báo, sau tất cả nó chỉ là một cảnh báo. Tuy nhiên, chương trình của bạn hiện chứa nhiều phiên bản của cùng một chức năng.

  • Sử dụng tùy chọn liên kết / NODEFAULTLIB: lib. Đây không phải là một giải pháp hoàn chỉnh, ngay cả khi bạn có thể khiến chương trình của mình liên kết theo cách này mà bạn đang bỏ qua một dấu hiệu cảnh báo: mã đã được biên dịch cho các môi trường khác nhau, một số mã của bạn có thể được biên dịch cho một mô hình luồng đơn trong khi mã khác là đa luồng.

  • [...] Truy tìm tất cả các thư viện của bạn và đảm bảo họ có các cài đặt liên kết chính xác

Trong phần sau, như đã đề cập trong bài viết gốc, hai vấn đề phổ biến có thể phát sinh:

  • Bạn có một thư viện bên thứ ba được liên kết khác với ứng dụng của bạn.

  • Bạn có các chỉ thị khác được nhúng trong mã của bạn: thông thường đây là MFC. Nếu bất kỳ mô-đun nào trong hệ thống của bạn liên kết với MFC, tất cả các mô-đun của bạn phải liên kết với cùng một phiên bản MFC.

Đối với những trường hợp đó, đảm bảo bạn hiểu vấn đề và quyết định trong số các giải pháp.


Lưu ý: Tôi muốn đưa bản tóm tắt liên kết của Yochai Timmer vào câu trả lời của riêng mình nhưng vì một số người gặp khó khăn khi xem lại các chỉnh sửa chính xác, tôi đã phải viết nó trong một câu trả lời riêng. Lấy làm tiếc


7

Tôi nhận được điều này mỗi khi tôi muốn tạo một ứng dụng trong VC ++.

Bấm chuột phải vào dự án, chọn Thuộc tính sau đó trong 'Thuộc tính cấu hình | C / C ++ | Tạo mã ', chọn "Gỡ lỗi đa luồng (/ MTd)" cho cấu hình Gỡ lỗi.

Lưu ý rằng điều này không thay đổi cài đặt cho cấu hình Phát hành của bạn - bạn sẽ cần đến cùng một vị trí và chọn "Đa luồng (/ MT)" cho Bản phát hành.


4

Bấm chuột phải vào dự án, chọn Thuộc tính sau đó trong 'Thuộc tính cấu hình | Trình liên kết | Đầu vào | Bỏ qua Thư viện cụ thể và viết msvcrtd.lib

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.