与Visual Studio 2010中的MD相反,无法在MT模式下编译简单的Qt程序

Cannot compile a simple Qt program in MT mode as opposed to MD in Visual Studio 2010

本文关键字:模式 MT 编译 简单 程序 Qt 2010 Studio Visual 中的 MD      更新时间:2023-10-16

我正试图在Visual Studio 2010中使用MTd而不是MDd进行编译(这样dll就打包好了,我不需要用exe来分发它们),但在编译过程中我不断收到"致命错误LNK1169:找到一个或多个多重定义符号"。MDd编译良好,但在其他计算机上没有MSVCP100.dll时无法工作。

我正在使用Qt的静态构建,并试图构建VS插件附带的默认Qt程序。

是否有其他方法可以强制链接器静态编译?我所要做的就是将一个Qt程序作为一个没有dll的exe来分发。

这是构建日志:

1>ClCompile:
1>  All outputs are up-to-date.
1>  cooltest1.cpp
1>  moc_cooltest1.cpp
1>  main.cpp
1>  Generating Code...
1>  All outputs are up-to-date.
1>  qrc_cooltest1.cpp
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: "public: __thiscall std::exception::exception(char const * const &)" (??0exception@std@@QAE@ABQBD@Z) already defined in LIBCMT.lib(stdexcpt.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: "public: virtual __thiscall std::exception::~exception(void)" (??1exception@std@@UAE@XZ) already defined in LIBCMT.lib(stdexcpt.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: "public: __thiscall std::exception::exception(class std::exception const &)" (??0exception@std@@QAE@ABV01@@Z) already defined in LIBCMT.lib(stdexcpt.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: _memmove already defined in LIBCMT.lib(memmove.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: _strncmp already defined in LIBCMT.lib(strncmp.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: _isupper already defined in LIBCMT.lib(_ctype.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: _isalpha already defined in LIBCMT.lib(_ctype.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: _isdigit already defined in LIBCMT.lib(_ctype.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: _isspace already defined in LIBCMT.lib(_ctype.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: _malloc already defined in LIBCMT.lib(malloc.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: _free already defined in LIBCMT.lib(free.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: __control87 already defined in LIBCMT.lib(_ieee87_.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: __clearfp already defined in LIBCMT.lib(_ieee87_.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: _strncpy_s already defined in LIBCMT.lib(strncpy_s.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: _strcpy_s already defined in LIBCMT.lib(strcpy_s.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: _realloc already defined in LIBCMT.lib(realloc.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: "public: __thiscall std::exception::exception(char const * const &,int)" (??0exception@std@@QAE@ABQBDH@Z) already defined in LIBCMT.lib(stdexcpt.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: _exit already defined in LIBCMT.lib(crt0dat.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: __errno already defined in LIBCMT.lib(dosmap.obj)
1>MSVCRT.lib(MSVCR100.dll) : error LNK2005: _abort already defined in LIBCMT.lib(abort.obj)
1>MSVCRT.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in LIBCMT.lib(typinfo.obj)
1>MSVCRT.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 LIBCMT.lib(typinfo.obj)
1>LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
1>c:usersusernamedocumentsvisual studio 2010ProjectsCoolTest1\CoolTest1.exe : fatal error LNK1169: one or more multiply defined symbols found
1>
1>Build FAILED.     

当您修补/MT时,这是一个标准的链接器错误。您现在正在将一些使用/MT编译的代码与一些使用/MD编译的代码链接起来,这些代码依赖于libcmt.lib中的CRT代码,因此依赖于msvcrt.lib中的CRT码。这是不允许的,您的程序中只能链接一个CRT。

您需要找到仍使用/MD编译的代码。这段代码很可能存在于.lib中,就像QT的运行时支持代码一样。如果QT没有支持静态链接CRT的.lib,那么就只能使用/MD了。这并不罕见,编写能够处理/MT的DLL中的代码是很困难的。

您可以重建QT以使用静态VC库。转到${QtDir}mkspecswin32-msvc2010qmake.conf,并更换

QMAKE_CFLAGS_RELEASE    = -O2 -MD
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi
QMAKE_CFLAGS_DEBUG      = -Zi -MDd

带有

QMAKE_CFLAGS_RELEASE    = -O2 -MT
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi
QMAKE_CFLAGS_DEBUG      = -Zi -MTd

在那之后,重新配置并重建qt

您静态链接程序并针对libcmt进行链接,但同时链接来自Qt DLL的代码,顾名思义,Qt DLL是针对msvcrt.lib动态链接的。

您需要动态链接或从源代码将Qt重新编译为静态,这并不困难,但很耗时。