使用静态链接的Boost库出现动态链接错误

3

我使用 Windows(MSVC 2012) 和 Boost v1.54,在编译 Boost.Log (我的小项目依赖它)时,使用了以下参数:

b2.exe link=static variant=release runtime-link=shared --with-log stage

所以,日志模块被编译并动态链接到C运行时库。

然后,我的小项目使用CMake进行管理,并添加选项以静态链接boost:

set(Boost_USE_STATIC_LIBS ON)

但是生成nmake makefile的过程失败了,出现了链接错误2038:

libboost_log-vc110-mt-1_54.lib(attribute_set.obj):-1: error: LNK2038:
  mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't
  match value 'MT_StaticRelease' in http_proxy_server.cpp.obj

如果我使用选项runtime-link=static编译boost,表示静态链接CRT,那么我就可以成功地制作我的项目。
我的问题是:有人能解释一下为什么我的项目无法与动态链接版本的boost链接到CRT,但是可以使用静态链接版本的boost链接到CRT吗?有什么区别?
顺便说一句:我的项目使用/MD选项动态链接到CRT。
编辑:
最终我找出了原因,我混淆了CMAKE_CXX_FLAGS_RELEASECMAKE_CXX_FLAGS,前者有一个/MD选项,但后者没有。事实上,cmake将后者传递给编译器,所以我的程序实际上是静态链接的,因为错误输出显示了这一点。
解决方案:在生成makefile时使用-DCMAKE_BUILD_TYPE=Release选项运行cmake,这将自动将CMAKE_CXX_FLAGS_RELEASE的选项添加到CMAKE_CXX_FLAGS中,然后程序将链接到CRT动态库。
哦,一个愚蠢的问题。

请查看此答案:https://dev59.com/Oms05IYBdhLWcg3wAdST - João Augusto
你尝试过添加 set( Boost_USE_STATIC_RUNTIME OFF ) 吗? - Daarx
@Daarx 我尝试过了,错误仍然存在。 - Kelvin Hu
你是否在 CMAKE_CXX_FLAGS 中手动设置了 /MD 选项?如果我没记错,当我遇到类似问题时,即使生成的 Visual Studio 项目据说已经设置了该标志,这个操作似乎也可以解决问题。我不知道为什么这对我起作用了。 - Daarx
1
@Daarx 是的,最终我找到了原因,是 CMAKE_CXX_FLAGS 的设置不当,请参见此问题的 编辑 部分。 - Kelvin Hu
显示剩余4条评论
1个回答

1
抱歉,这个问题是我自己提出的,最终我找到了原因,并将解决方案粘贴在问题的编辑部分。但@TobiMcNamobi建议即使是我自己提出的问题也要给出答案。所以我在这里贴出答案:
我混淆了CMAKE_CXX_FLAGS_RELEASECMAKE_CXX_FLAGS,前者有一个/MD选项,而后者没有。实际上,cmake会将后者传递给编译器,因此我的程序实际上是静态链接的,正如错误输出所示。
解决方案:在生成makefile时使用-DCMAKE_BUILD_TYPE=Release运行cmake,这将自动将CMAKE_CXX_FLAGS_RELEASE的选项添加到CMAKE_CXX_FLAGS中,然后程序将动态链接到CRT。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接