msvcrt.lib 與 libcmt.lib 衝突的解決方式
有時候我們會遇見諸如 libcmt.lib/msvcrt.lib/msvcprt.lib 之間出現重覆定義的問題,這是因為程式間所連結進來,各個 library 之間的 CRT 版本不一致的關係。
在 MSVC++ 2005 中,Properties 中的 Code Generation 可以選擇 Runtime Library,共有四種選擇,它們會各自對應到四種 library:
Multi-threaded (/MT) - libcmt.lib
Multi-threaded Debug (/MTd) - libcmtd.lib
Multi-threaded DLL (/MD) - msvcrt.lib
Multi-threaded Debug DLL (/MDd) - msvcrtd.lib
等於說我們選了其中一項,MSVC 就會自動幫我們連結相對應的 CRT 版本(前提是有使用 C 的函式。不過,應該大家都會用吧?!)。至於 msvcprt.lib 與 msvcprtd.lib 則是對應到 Release 及 Debug 版本的 C++ Runtime Library(只要程式中有使用到 C++ function,MSVC 自動會連結進來)。
在程式中所連結進來的各個 library,其 Runtime Library 選項都得一致。假如我們在連結時出現以下錯誤:
1>Linking...
1>msvcprt.lib(MSVCP80.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in Check3G.lib(CheckApi.obj)
1>LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
上面的錯誤是說,程式要連結 msvcprt.lib 中時,發現同一個符號在 Check3G.lib 中已經定義過了(最後一行指明已經在 libcmt.lib 中定義過了)。這個例子原因是,Check3G.lib 使用 Multi-threaded (/MT) 選項,連結 libcmt.lib 進來;但程式本身使用 Multi-threaded DLL (/MD),連結 msvcprt.lib 進來。如此當然會有衝突囉!
解決方式就是將 Check3G.lib 重新編譯,使用 Multi-threaded DLL (/MD) 選項,就可以解決了。那如果 Check3G.lib 是 3rd party 提供,我們沒原始碼呢?解決方式就是使用 MSVC 中的 Ignore Specific Library(Linker/Input 選項),將衝突的 library 給 ignore 掉就可以啦!
底下是使用 dumpbin 查看程式 dependency 的結果。先列出來的是使用 Multi-threaded (/MT) 的方式,CRT 是直接 static 連結進程式,故在 dependency 中看不到相對應的 dll。
File Type: EXECUTABLE IMAGE
Image has the following dependencies:
AsDiag.dll
QtCore4.dll
QtGui4.dll
AsMultiTouch.dll
POWRPROF.dll
KERNEL32.dll
USER32.dll
ADVAPI32.dll
SHELL32.dll
ole32.dll
OLEAUT32.dll
QMSL_MSVC6R.dll
Summary
C000 .data
3C000 .rdata
33000 .text
而下面是使用 Multi-threaded DLL (/MD) 的結果。可以看出 MSVCP80.dll/MSVCR80.dll 這兩個 dll 變成程式的 dependency。
File Type: EXECUTABLE IMAGE
Image has the following dependencies:
AsDiag.dll
QtCore4.dll
QtGui4.dll
AsMultiTouch.dll
POWRPROF.dll
KERNEL32.dll
USER32.dll
ADVAPI32.dll
SHELL32.dll
ole32.dll
OLEAUT32.dll
MSVCP80.dll
MSVCR80.dll
QMSL_MSVC6R.dll
在 MSVC++ 2005 中,Properties 中的 Code Generation 可以選擇 Runtime Library,共有四種選擇,它們會各自對應到四種 library:
Multi-threaded (/MT) - libcmt.lib
Multi-threaded Debug (/MTd) - libcmtd.lib
Multi-threaded DLL (/MD) - msvcrt.lib
Multi-threaded Debug DLL (/MDd) - msvcrtd.lib
等於說我們選了其中一項,MSVC 就會自動幫我們連結相對應的 CRT 版本(前提是有使用 C 的函式。不過,應該大家都會用吧?!)。至於 msvcprt.lib 與 msvcprtd.lib 則是對應到 Release 及 Debug 版本的 C++ Runtime Library(只要程式中有使用到 C++ function,MSVC 自動會連結進來)。
在程式中所連結進來的各個 library,其 Runtime Library 選項都得一致。假如我們在連結時出現以下錯誤:
1>Linking...
1>msvcprt.lib(MSVCP80.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in Check3G.lib(CheckApi.obj)
1>LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
上面的錯誤是說,程式要連結 msvcprt.lib 中時,發現同一個符號在 Check3G.lib 中已經定義過了(最後一行指明已經在 libcmt.lib 中定義過了)。這個例子原因是,Check3G.lib 使用 Multi-threaded (/MT) 選項,連結 libcmt.lib 進來;但程式本身使用 Multi-threaded DLL (/MD),連結 msvcprt.lib 進來。如此當然會有衝突囉!
解決方式就是將 Check3G.lib 重新編譯,使用 Multi-threaded DLL (/MD) 選項,就可以解決了。那如果 Check3G.lib 是 3rd party 提供,我們沒原始碼呢?解決方式就是使用 MSVC 中的 Ignore Specific Library(Linker/Input 選項),將衝突的 library 給 ignore 掉就可以啦!
底下是使用 dumpbin 查看程式 dependency 的結果。先列出來的是使用 Multi-threaded (/MT) 的方式,CRT 是直接 static 連結進程式,故在 dependency 中看不到相對應的 dll。
File Type: EXECUTABLE IMAGE
Image has the following dependencies:
AsDiag.dll
QtCore4.dll
QtGui4.dll
AsMultiTouch.dll
POWRPROF.dll
KERNEL32.dll
USER32.dll
ADVAPI32.dll
SHELL32.dll
ole32.dll
OLEAUT32.dll
QMSL_MSVC6R.dll
Summary
C000 .data
3C000 .rdata
33000 .text
而下面是使用 Multi-threaded DLL (/MD) 的結果。可以看出 MSVCP80.dll/MSVCR80.dll 這兩個 dll 變成程式的 dependency。
File Type: EXECUTABLE IMAGE
Image has the following dependencies:
AsDiag.dll
QtCore4.dll
QtGui4.dll
AsMultiTouch.dll
POWRPROF.dll
KERNEL32.dll
USER32.dll
ADVAPI32.dll
SHELL32.dll
ole32.dll
OLEAUT32.dll
MSVCP80.dll
MSVCR80.dll
QMSL_MSVC6R.dll
留言
張貼留言