VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的

  • Post author:
  • Post category:其他


转自


http://blog.csdn.net/atfield/archive/2007/03/11/1526253.aspx





MSDN


中对于在不同的配置下


Link





LIB


作了说明:




C Runtime Library












开关







对应的库







版本






/MD


MSVCRT.LIB


多线程


DLL





Release


版本



/MDd


MSVCRTD.LIB


多线程


DLL





Debug


版本



/MT


LIBCMT.LIB


多线程静态链接的


Release


版本



/MTd


LIBCMTD.LIB


多线程静态链接的


Debug


版本



/clr


MSVCMRT.LIB


托管代码和非托管代码混合



/clr:pure


MSVCURT.LIB


纯托管代码





C++ Standard Library












开关







对应的库







版本






/MD


MSVCPRT.LIB


多线程


DLL





Release


版本



/MDd


MSVCPRTD.LIB


多线程


DLL





Debug


版本



/MT


LIBCPMT.LIB


多线程静态链接的


Release


版本



/MTd


LIBCPMTD.LIB


多线程静态链接的


Debug


版本




编译器会自动根据编译选项,选择对应的


LIB


文件。一般情况下这不会出现问题。



然而,在部分情况下,一旦你的程序的各个部分(


LIB, OBJ…


)并非由相同的编译选项编译出,而


Link


在一起的话,会出现各种各样的看似很难解决的问题,这类问题主要以重复定义的错误形式存在,通常的解决方法也很简单,就是选择同样的编译选项进行编译之后再


Link








Case Study



之前刚下载了


ANTLR


,在准备编译它的


Example


的时候发现了下面的


Build


错误(我自己为这个例子创建了


VS


的项目,当前配置为动态链接Runtime库,


Debug版


):



1>msvcprtd.lib(MSVCP80D.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 antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::replace(unsigned int,unsigned int,char const *,unsigned int)” (?replace@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@IIPBDI@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: void __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::reserve(unsigned int)” (?reserve@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXI@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: unsigned int __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::length(void)const ” (?length@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::operator+=(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)” (??Y?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@ABV01@@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.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> >(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)” (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: char const & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::operator[](unsigned int)const ” (??A?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEABDI@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::operator=(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)” (??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@ABV01@@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::operator=(char const *)” (??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@PBD@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.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> >(char const *)” (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl std::operator+<char,struct std::char_traits<char>,class std::allocator<char> >(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)” (??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@ABV10@0@Z) already defined in antlr.lib(MismatchedCharException.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: char const * __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::c_str(void)const ” (?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “bool __cdecl std::operator<<char,struct std::char_traits<char>,class std::allocator<char> >(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)” (??$?MDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall std::basic_ostream<char,struct std::char_traits<char> >::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > & (__cdecl*)(class std::basic_ostream<char,struct std::char_traits<char> > &))” (??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall std::basic_ostream<char,struct std::char_traits<char> >::operator<<(int)” (??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::endl(class std::basic_ostream<char,struct std::char_traits<char> > &)” (?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: void __thiscall std::basic_ios<char,struct std::char_traits<char> >::setstate(int,bool)” (?setstate@?$basic_ios@DU?$char_traits@D@std@@@std@@QAEXH_N@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: int __thiscall std::ios_base::width(int)” (?width@ios_base@std@@QAEHH@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: int __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::sputn(char const *,int)” (?sputn@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEHPBDH@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: static bool __cdecl std::char_traits<char>::eq_int_type(int const &,int const &)” (?eq_int_type@?$char_traits@D@std@@SA_NABH0@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: static int __cdecl std::char_traits<char>::eof(void)” (?eof@?$char_traits@D@std@@SAHXZ) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: int __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::sputc(char)” (?sputc@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEHD@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: class std::basic_streambuf<char,struct std::char_traits<char> > * __thiscall std::basic_ios<char,struct std::char_traits<char> >::rdbuf(void)const ” (?rdbuf@?$basic_ios@DU?$char_traits@D@std@@@std@@QBEPAV?$basic_streambuf@DU?$char_traits@D@std@@@2@XZ) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: char __thiscall std::basic_ios<char,struct std::char_traits<char> >::fill(void)const ” (?fill@?$basic_ios@DU?$char_traits@D@std@@@std@@QBEDXZ) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: int __thiscall std::ios_base::flags(void)const ” (?flags@ios_base@std@@QBEHXZ) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: int __thiscall std::ios_base::width(void)const ” (?width@ios_base@std@@QBEHXZ) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: static unsigned int __cdecl std::char_traits<char>::length(char const *)” (?length@?$char_traits@D@std@@SAIPBD@Z) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall std::basic_ostream<char,struct std::char_traits<char> >::flush(void)” (?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: class std::basic_ostream<char,struct std::char_traits<char> > * __thiscall std::basic_ios<char,struct std::char_traits<char> >::tie(void)const ” (?tie@?$basic_ios@DU?$char_traits@D@std@@@std@@QBEPAV?$basic_ostream@DU?$char_traits@D@std@@@2@XZ) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: bool __thiscall std::ios_base::good(void)const ” (?good@ios_base@std@@QBE_NXZ) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: void __thiscall std::basic_ostream<char,struct std::char_traits<char> >::_Osfx(void)” (?_Osfx@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEXXZ) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: void __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::_Lock(void)” (?_Lock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXXZ) already defined in antlr.lib(CharScanner.obj)


1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “public: void __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::_Unlock(void)” (?_Unlock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXXZ) already defined in antlr.lib(CharScanner.obj)



1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: “class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::operator<<<char,struct std::char_traits<char>,class std::allocator<char> >(class std::basic_ostream<char,struct std::char_traits<char> > &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)” (??$?6DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z) already defined in antlr.lib(LLkParser.obj)


1>libcpmt.lib(locale0.obj) : error LNK2005: “private: static class std::locale::_Locimp * __cdecl std::locale::_Getgloballocale(void)” (?_Getgloballocale@locale@std@@CAPAV_Locimp@12@XZ) already defined in msvcprtd.lib(MSVCP80D.dll)


1>libcpmt.lib(locale0.obj) : error LNK2005: “private: static void __cdecl std::locale::facet::facet_Register(class std::locale::facet *)” (?facet_Register@facet@locale@std@@CAXPAV123@@Z) already defined in msvcprtd.lib(MSVCP80D.dll)


1>libcpmt.lib(locale0.obj) : error LNK2005: “public: static void __cdecl std::_Locinfo::_Locinfo_dtor(class std::_Locinfo *)” (?_Locinfo_dtor@_Locinfo@std@@SAXPAV12@@Z) already defined in msvcprtd.lib(MSVCP80D.dll)


1>libcpmt.lib(locale0.obj) : error LNK2005: “public: static void __cdecl std::_Locinfo::_Locinfo_ctor(class std::_Locinfo *,char const *)” (?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@PBD@Z) already defined in msvcprtd.lib(MSVCP80D.dll)


1>libcpmt.lib(xmutex.obj) : error LNK2005: “public: void __thiscall std::_Mutex::_Lock(void)” (?_Lock@_Mutex@std@@QAEXXZ) already defined in msvcprtd.lib(MSVCP80D.dll)


1>libcpmt.lib(xmutex.obj) : error LNK2005: “public: void __thiscall std::_Mutex::_Unlock(void)” (?_Unlock@_Mutex@std@@QAEXXZ) already defined in msvcprtd.lib(MSVCP80D.dll)


1>libcpmt.lib(xlock.obj) : error LNK2005: “public: __thiscall std::_Lockit::_Lockit(int)” (??0_Lockit@std@@QAE@H@Z) already defined in msvcprtd.lib(MSVCP80D.dll)


1>libcpmt.lib(xlock.obj) : error LNK2005: “public: __thiscall std::_Lockit::~_Lockit(void)” (??1_Lockit@std@@QAE@XZ) already defined in msvcprtd.lib(MSVCP80D.dll)


1>LIBCMT.lib(invarg.obj) : error LNK2005: __invoke_watson already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(invarg.obj) : error LNK2005: __invalid_parameter already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(setlocal.obj) : error LNK2005: __configthreadlocale already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(tidtable.obj) : error LNK2005: __encode_pointer already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(tidtable.obj) : error LNK2005: __decode_pointer already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(tolower.obj) : error LNK2005: _tolower already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(crt0dat.obj) : error LNK2005: __amsg_exit already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(crt0dat.obj) : error LNK2005: __initterm_e already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(crt0dat.obj) : error LNK2005: _exit already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(crt0dat.obj) : error LNK2005: __exit already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(crt0dat.obj) : error LNK2005: __cexit already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(lconv.obj) : error LNK2005: _localeconv already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(mlock.obj) : error LNK2005: __unlock already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(mlock.obj) : error LNK2005: __lock already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(winxfltr.obj) : error LNK2005: __XcptFilter already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(crt0init.obj) : error LNK2005: ___xi_a already defined in MSVCRTD.lib(cinitexe.obj)


1>LIBCMT.lib(crt0init.obj) : error LNK2005: ___xi_z already defined in MSVCRTD.lib(cinitexe.obj)


1>LIBCMT.lib(crt0init.obj) : error LNK2005: ___xc_a already defined in MSVCRTD.lib(cinitexe.obj)


1>LIBCMT.lib(crt0init.obj) : error LNK2005: ___xc_z already defined in MSVCRTD.lib(cinitexe.obj)


1>LIBCMT.lib(hooks.obj) : error LNK2005: “void __cdecl terminate(void)” (?terminate@@YAXXZ) already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(crt0.obj) : error LNK2005: _mainCRTStartup already defined in MSVCRTD.lib(crtexe.obj)


1>LIBCMT.lib(errmode.obj) : error LNK2005: ___set_app_type already defined in MSVCRTD.lib(MSVCR80D.dll)


1>LIBCMT.lib(_ctype.obj) : error LNK2005: _isprint already defined in MSVCRTD.lib(MSVCR80D.dll)


1>MSVCRTD.lib(MSVCR80D.dll) : error LNK2005: __stricmp already defined in LIBCMT.lib(stricmp.obj)


1>LINK : warning LNK4098: defaultlib ‘MSVCRTD’ conflicts with use of other libs; use /NODEFAULTLIB:library


1>LINK : warning LNK4098: defaultlib ‘LIBCMT’ conflicts with use of other libs; use /NODEFAULTLIB:library


1>D:/home/doc/Visual Studio 2005/Projects/tst_antlr_3/Debug/tst_antlr_3.exe : fatal error LNK1169: one or more multiply defined symbols found


分析一下错误来源,会发现:




1.





错误来源主要是重复定义的问题,而且重复定义的基本上都是


VC Runtime





Standard C++ Library


中的函数




2.





LIBCMT





LIBCPMT





Release


下的


Lib


,本来不应该出现在


Debug


版本的链接的


Lib







3.





重复定义的问题主要出现在:


LIBCMT, LIBCPMT, MSVCPRTD, MSVCRTD


来看看出问题的


LIB


是那些:




1.





LIBCMT





C Runtime


库的多线程静态链接的


Release


版本




2.





LIBCPMT





C++ Standard Library


的多线程静态链接的


Release


版本




3.





MSVCPRTD





C++ Standard Library


的多线程


DLL





Debug


版本




4.





MSVCRTD





C Runtime Library


的多线程


DLL





Debug


版本



当前我们的配置是多线程


DLL





Debug


版,因此


3





4


是应该出现在


link


的列表中的,不属于多余。而后两者则是只是当多线程静态链接


Release


版中才会出现。这提示我在项目中加入的


ANTLR.LIB


可能是造成这个问题的根源,因为静态库的编译选项很容易和主程序发生冲突,并且根据实际信息我们可以看出


ANTLR.LIB


应该是用多线程静态链接的


Release


版本来编译的。



这样,解决方法就很清楚了:




1.





切换到


Release


,因为


ANTLR.LIB


是在


Release


下面编译的




2.








Run Time


库的版本修改成多线程静态链接



做了这两个修改之后编译通过。



还有一种方法是,自己用多线程


DLL





Debug


版重新编译一次


ANTLR


,生成一个新的


ANTLRD.LIB


,再


link


这个


Lib


也可以解决这个问题。



Summary



1.





知道各个不同的


LIB


代表的版本信息非常重要,可以帮助快速定位问题




2.





在编程的时候,一定要把所有的项目的编译选项(是静态链接


Runtime


库还是动态链接


Runtime


库,


Debug/Release


)配置成一样的。如果部分


LIB/OBJ


是由第三方提供(


OBJ


情况很少见),一般情况下只能调整自己的编译选项,除非你可以要求第三方提供其他版本的编译好的


LIB



3.





在发布可重用的静态


LIB


库供其他人调用的时候,最好对应不同的编译选项,乃至


VC


版本,提供不同版本的


LIB





VC


自己的


Runtime


就是最好的例子。



版权声明:本文为prleader原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。