Невозможно скомпилировать простую программу Qt в режиме MT, в отличие от MD в Visual Studio 2010 - PullRequest
11 голосов
/ 26 июня 2011

Я пытаюсь скомпилировать, используя MTd в Visual Studio 2010 вместо MDd (так, чтобы dll были упакованы, и мне не нужно было распространять их вместе с моим exe), но я продолжаю получать «фатальную ошибку LNK1169: один или более многократно определенных символов, найденных "во время компиляции. MDd компилируется нормально, но не работает без MSVCP100.dll на других компьютерах.

Я использую статическую сборку Qt и пытаюсь собрать программу Qt по умолчанию, которая поставляется с надстройкой VS.

Есть ли другой способ заставить компоновщик компилироваться статически? Все, что я пытаюсь сделать, это распространять программу Qt как исполняемый файл без DLL.

Вот журнал сборки:

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:\users\username\documents\visual studio 2010\Projects\CoolTest1\\CoolTest1.exe : fatal error LNK1169: one or more multiply defined symbols found
1>
1>Build FAILED.     

Ответы [ 3 ]

14 голосов
/ 26 июня 2011

Это стандартная ошибка компоновщика при работе с / MT.Теперь вы связываете некоторый код, который был скомпилирован с / MT и, следовательно, имеет зависимость от кода CRT в libcmt.lib с некоторым кодом, который был скомпилирован с / MD и, таким образом, имеет зависимость от кода CRT в msvcrt.lib.Это недопустимо, может быть только одна CRT, связанная с вашей программой.

Вам нужно будет найти код, который все еще компилируется с / MD.Этот код вполне может существовать в .lib, как и код поддержки времени выполнения для QT.Если у QT нет .lib, который поддерживает статическое связывание CRT, то вы застряли с / MD.Это не редкость, писать код, который находится в DLL, который может иметь дело с / MT, сложно.

10 голосов
/ 27 июня 2011

вы можете пересобрать QT, чтобы использовать статические библиотеки VC. Перейдите на ${QtDir}\mkspecs\win32-msvc2010\qmake.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

2 голосов
/ 26 июня 2011

Вы связываете свою программу статически и ссылаетесь на libcmt, но в то же время связываете код из библиотек Qt, которые, как уже сказано в названии, динамически связаны с msvcrt.lib.

Вам нужно будет либо динамически связать, либо перекомпилировать Qt из источника как статический, что не сложно, но требует много времени.

...