天天看點

warning LNK4098: defaultlib "MSVCRT" conflicts with use of other libs; use /NODE

剛編譯了DCMTK,運作一個小例子,出現如此錯誤:

1>------ Build started: Project: TestA, Configuration: Debug Win32 ------ 1>Linking... 1>msvcrtd.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in LIBCMTD.lib(typinfo.obj) 1>msvcrtd.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) already defined in LIBCMTD.lib(typinfo.obj) 1>LIBCMTD.lib(crt0init.obj) : warning LNK4098: defaultlib 'msvcrtd.lib' conflicts with use of other libs; use /NODEFAULTLIB:library 1>D:\VSWorkSpace\TestA\Debug\TestA.exe : fatal error LNK1169: one or more multiply defined symbols found

在網上搜了一下。原來問題出在預設庫的引用選擇上。

--------------------------------------------------------------------------------

VS2008,項目——屬性——配置屬性——C/C++——代碼生成:他有/MT,/MTd,/Md,/MDd四個選項,你必須讓所有使用的庫都使用相同的配置,否則就會有相應的提示,甚至可能會出現無法解析的函數。有時我們使用的庫不是自己可以控制的,那麼就隻能把工程屬性設定成和你使用的庫相同的選項。

錯誤 1 error LNK2005: _free 已經在 libcmtd.lib(dbgheap.obj) 中定義         MSVCRT.lib

錯誤 2 error LNK2005: _malloc 已經在 libcmtd.lib(dbgheap.obj) 中定義     MSVCRT.lib

.....

如果有一堆的重定義錯誤發生在同一個lib中,而且跟它沖突的也是同一個lib,那麼這個兩個lib的功能應該是一樣的,可以2選一,隻要在“忽略特定的庫”内填入需要忽略的庫。

項目屬性-配置屬性-連結器-輸入-忽略特定的庫:libcmtd.lib

項目屬性-配置屬性-正常-MFC的使用:在共享 DLL 中使用 MFC

MSVCRT.lib 和libcmt.lib的沖突還是比較常見的。

從錯誤資訊可以看出是msvcrt.lib和libcmt.lib庫中重複定義了__isctype等符号。為什麼會出現這樣的問題呢?這就要從這兩個庫的作用說起了。

msvcrt.lib是VC中的Multithreaded DLL 版本的C運作時庫,而libcmt.lib是Multithreaded的運作時庫。在同一個項目中,所有的源檔案必須連結相同的C運作時庫。如果某一文 件用了Multithreaded DLL版本,而其他檔案用了Single-Threaded或者Multithreaded版本的庫,也就是說用了不同的庫,就會導緻這個警告的出現。

告警資訊的意思我們明白之後,就要找造成這個問題的原因了。在項目設定中我們可以看到目前項目使用的是Multithreaded非DLL版本的運 行時庫,這說明項目中還有其他檔案用到了不是這個版本的運作時庫。很顯然,就是openssl的靜态庫。檢視openssl中ms下的nt.mak,我們 可以發現靜态庫版本中openssl使用編譯開關/MD進行編譯的,也就是說openssl靜态庫是預設用的Multithreaded DLL 版本的C運作時庫。

原因找到了。那麼解決方法,很明顯有兩個。總之就是将兩個項目的運作時庫統一。

簡單的方式就是将項目的動态庫修改為使用Multithreaded DLL 版本的C運作時庫即可。 某些情況下你的項目可能不能改變目前的運作時庫,你可以将openssl的nt.mak中的/MD開關修改為/MT然後重新編譯openssl靜态庫就可以了。

預設庫“library”與其他庫的使用沖突;請使用 /NODEFAULTLIB:library LNK4098 的解決辦法

您試圖與不相容的庫連結。

注意 運作時庫現在包含可防止混合不同類型的指令。如果試圖在同一個程式中使用不同類型的運作 時庫或使用調試和非調試版本的運作時庫,則将收到此警告。例如,如 果編譯一個檔案以使用一種運作時庫,而編譯另一個檔案以使用另一種運作時庫(例如單線程運作時庫對多線程運作時庫),并試圖連結它們,則将得到此警告。應 将所有源檔案編譯為使用同一個運作時庫。有關更多資訊,請參見使用運作時庫(/MD、/MT 和 /LD)編譯器選項。

可以 使用連結器的 /VERBOSE:LIB 開關來确定連結器搜尋的庫。如果收到 LNK4098,并想建立使用如單線程、非調試運作時庫的可執行檔案,請使用 /VERBOSE:LIB 選項确定連結器搜尋的庫。連結器作為搜尋的庫輸出的應是 LIBC.lib,而非 LIBCMT.lib、MSVCRT.lib、LIBCD.lib、LIBCMTD.lib 和 MSVCRTD.lib。對每個要忽略的庫可以使用 /NODEFAULTLIB,以通知連結器忽略錯誤的運作時庫。

下表顯示根據要使用的運作時庫應忽略的庫。

若要使用第一行運作時庫    請忽略第2行的這些庫 單線程 (libc.lib) libcmt.lib、msvcrt.lib、libcd.lib、libcmtd.lib、msvcrtd.lib

多線程 (libcmt.lib) libc.lib、msvcrt.lib、libcd.lib、libcmtd.lib、msvcrtd.lib

使用 DLL 的多線程 (msvcrt.lib) libc.lib、libcmt.lib、libcd.lib、libcmtd.lib、msvcrtd.lib

調試單線程 (libcd.lib) libc.lib、libcmt.lib、msvcrt.lib、libcmtd.lib、msvcrtd.lib

調試多線程 (libcmtd.lib) libc.lib、libcmt.lib、msvcrt.lib、libcd.lib、msvcrtd.lib

使用 DLL 的調試多線程 (msvcrtd.lib) libc.lib、libcmt.lib、msvcrt.lib、libcd.lib、libcmtd.lib

例如,如果收到此警告,并希望建立使用非調試、單線程版本的運作時庫的可執行檔案,可以将下列選項與連結器一起使用:

/NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib

=================================================================

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

Linker Tools Warning LNK4098 defaultlib "library" conflicts with use of other libs; use /NODEFAULTLIB:library

You are trying to link with incompatible libraries.

Important   The run-time libraries now contain directives to prevent mixing different types. You’ll receive this warning if you try to use different types or debug and non-debug versions of the run-time library in the same program. For example, if you compiled one file to use one kind of run-time library and another file to use another kind (for example, single-threaded versus multithreaded) and tried to link them, you’ll get this warning. You should compile all source files to use the same run-time library. See the Use Run-Time Library (MD, /ML, /MT, /LD) compiler options for more information.

You can use the linker’s /VERBOSE:LIB switch to determine which libraries the linker is searching. If you receive LNK4098 and want to create an executable file that uses, for example, the single-threaded, non-debug run-time libraries, use the /VERBOSE:LIB option to find out which libraries the linker is searching. The linker should print LIBC.LIB and not LIBCMT.LIB, MSVCRT.LIB, LIBCD.LIB, LIBCMTD.LIB, or MSVCRTD.LIB as the libraries searched. You can tell the linker to ignore the the incorrect run-time libraries by typing the incorrect libraries in the Ignore Libraries text box on the Link tab of the Settings dialog box in Developer’s Studio or by using the /NODEFAULTLIB:library option with LINK for each library you want to ignore. See the Ignore Libraries (/NODEFAULTLIB) linker option for more information.

The table below shows which libraries should be ignored depending on which run-time library you want to use.

To use this run-time library Ignore these libraries Single-threaded (libc.lib) libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib Multithreaded (libcmt.lib) libc.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib Multithreaded using DLL (msvcrt.lib) libc.lib, libcmt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib Debug Single-threaded (libcd.lib) libc.lib, libcmt.lib, msvcrt.lib, libcmtd.lib, msvcrtd.lib Debug Multithreaded (libcmtd.lib) libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, msvcrtd.lib Debug Multithreaded using DLL (msvcrtd.lib) libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib

For example, if you received this warning and you want to create an executable file that uses the non-debug, single-threaded version of the run-time libraries, you could use the following options with the linker:

/NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib

預設庫“library”與其他庫的使用沖突;使用 /NODEFAULTLIB:library

您試圖與不相容的庫連結。

重要事項 運作時庫現在包含防止混合不同類型的指令。如果試圖在同一個程式中使用不同類型的運作時庫或使用調試和非調試版本的運作時庫,則将收到此警告。例如,如果編譯一個檔案以使用一種運作時庫,而編譯另一個檔案以使用另一種運作時庫(例如單線程運作時庫對多線程運作時庫),并試圖連結它們,則将得到此警告。應将所有源檔案編譯為使用同一個運作時庫。有關更多資訊,請參閱使用運作時庫(/MD、/ML、/MT、/LD)編譯器選項。 可以使用連結器的 /VERBOSE:LIB 開關來确定連結器搜尋的庫。如果收到 LNK4098,并想建立使用如單線程、非調試運作時庫的可執行檔案,請使用 /VERBOSE:LIB 選項确定連結器搜尋的庫。連結器作為搜尋的庫輸出的應是 LIBC.lib,而非 LIBCMT.lib、MSVCRT.lib、LIBCD.lib、LIBCMTD.lib 和 MSVCRTD.lib。對每個要忽略的庫可以使用 /NODEFAULTLIB,以通知連結器忽略錯誤的運作時庫。

下表顯示根據要使用的運作時庫應忽略的庫。

若要使用此運作時庫 請忽略這些庫 單線程 (libc.lib) libcmt.lib、msvcrt.lib、libcd.lib、libcmtd.lib、msvcrtd.lib 多線程 (libcmt.lib) libc.lib、msvcrt.lib、libcd.lib、libcmtd.lib、msvcrtd.lib 使用 DLL 的多線程 (msvcrt.lib) libc.lib、libcmt.lib、libcd.lib、libcmtd.lib、msvcrtd.lib 調試單線程 (libcd.lib) libc.lib、libcmt.lib、msvcrt.lib、libcmtd.lib、msvcrtd.lib 調試多線程 (libcmtd.lib) libc.lib、libcmt.lib、msvcrt.lib、libcd.lib、msvcrtd.lib 使用 DLL 的調試多線程 (msvcrtd.lib) libc.lib、libcmt.lib、msvcrt.lib、libcd.lib、libcmtd.lib

例如,如果收到此警告,并希望建立使用非調試、單線程版本的運作時庫的可執行檔案,可以将下列選項與連結器一起使用:

/NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB

繼續閱讀