【问题标题】:POCO: When compiling project in Release, linker asks for MT instead of MD libsPOCO:在 Release 中编译项目时,链接器要求 MT 而不是 MD 库
【发布时间】:2016-12-18 09:15:57
【问题描述】:

我有一个使用 MD 构建库(PocoFoundationmdd.lib 等)的调试版本的 VS2012 项目。 #POCO_STATIC 已定义 - 一切都很好。

Release 模式下编译时,我使用的是相同库的发布版本 (PocoFoundationmd.lib) - 但是 VS2012 然后突然拒绝链接并要求MT 版本(PocoFoundationmt.lib)

error LNK1104: cannot open file 'PocoFoundationmt.lib'  

是什么导致 POCO/VS 在 Release 模式下寻找 MT 版本而不是 MD 版本?有什么想法吗?

这是 VS2012 在 DEBUG 模式下使用的链接器命令(有效)

/OUT:"C:\xxx...\xxx.dll" /MANIFEST /NXCOMPAT /PDB:"C:\xxx...\xxx.pdb" /DYNAMICBASE "ssleay32.lib" "libeay32.lib" "cpprest120d_2_8.lib" "log4cppD.lib" "winhttp.lib" "Crypt32.lib" "Bcrypt.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /IMPLIB:"C:\xxx...\xxx.lib" /DEBUG /DLL /MACHINE:X86 /INCREMENTAL /PGD:"C:\xxx...\xxx.pgd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Debug\xxx.dll.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"..\libs\Poco\Debug" /TLBID:1  

.. 这是 RELEASE 模式的链接器命令(不起作用)

/OUT:"C:\xxx...\xxx.dll" /MANIFEST /LTCG /NXCOMPAT /PDB:"C:\xxx...\xxx.pdb" /DYNAMICBASE "ssleay32.lib" "libeay32.lib" "cpprest120_2_8.lib" "log4cppLIB.lib" "winhttp.lib" "Crypt32.lib" "Bcrypt.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /IMPLIB:"C:\xxx...\xxx.lib" /DEBUG /DLL /MACHINE:X86 /OPT:REF /SAFESEH /INCREMENTAL:NO /PGD:"C:\xxx...\xxx.pgd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Release\xxx.dll.intermediate.manifest" /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"..\libs\Poco\Release" /TLBID:1 

【问题讨论】:

标签: c++ visual-studio-2012 linker poco poco-libraries


【解决方案1】:

如果不看你的编译命令行是什么样子就很难说。也许您在其中一个标题中定义了 POCO_STATIC ?在已经包含Foundation.h 之后可能会遇到该定义,并且链接将根据this logic 进行。发布和调试之间的包含可能存在差异。或者,您实际上可能在调试中链接了mtd.lib,并且构建了 `PocoFoundationmtd.lib 但没有构建 PocoFoundationmt.lib,因此发布构建找不到它。

阅读this answer 可能会有所帮助。

【讨论】:

    【解决方案2】:

    POCO_STATIC_DLL 添加到预处理器定义中修复了它!

    (我还将同一个项目中的所有其他 LIBS 重新编译为 MD - 因为那里有一些 MT 库。)

    谢谢!

    【讨论】:

    • 从不自己定义_DLL。它是一个内置宏,在您使用 /MD 时自动定义。您隐藏了一个构建错误,它可能导致非常严重的链接器错误和非常讨厌的运行时错误。你有确凿的证据表明某些代码是用 /MT 编译的,你必须找到它。
    • 我认为你是 100% 正确的汉斯。再次检查所有设置并确保所有 C++ > 代码生成 > 运行时库都设置为 /MD - 它可以在预处理器定义中没有 _DLL 的情况下工作。当我遇到这些问题时,一定是某个地方的 /MT。
    【解决方案3】:

    在调试模式下编译的库通常与发布模式库完全不同,原因有很多:

    • 它们可能有错误处理/调试消息,这些消息在 Release 中对编译器不可见
    • Debug 和 Release 之间的代码优化差异可能足以防止交叉编译
    • 在某些情况下,调试和发布之间的整个功能级别可能会有所不同。

    一般来说,除非您自己专门负责生成这些库,否则您需要为 Debug 和 Release 获取单独的版本,并确保您的项目配置为为每个配置获取正确的版本。

    【讨论】:

    • @NjålArneGjermundshaug 您可能希望提供更多源代码,因为简单地说“我正在定义#POCO_STATIC”并不一定表明它被正确使用。
    • #define POCO_STATIC 包含在使用 POCO 的 cpp 文件的顶部。该解决方案在 DEBUG 模式下编译并运行良好。我的发布配置与调试相同 - 除了 POCO 发布库包含在库目录中 - 而不是调试库。 POCO_STATIC 包含在调试和发布配置的预处理器定义中。它在调试中编译得很好 - 链接器查找并使用库的 MDD 版本。在 Release 中 - 链接器应该使用库的 MD 版本 - 但出于某种原因它坚持使用 MT 版本。
    猜你喜欢
    • 2012-12-19
    • 1970-01-01
    • 2015-04-10
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 2014-10-17
    • 1970-01-01
    相关资源
    最近更新 更多