【问题标题】:Visual Studio (C++) is automatically linking against an unwanted version of lib fileVisual Studio (C++) 自动链接到不需要的 lib 文件版本
【发布时间】:2016-02-13 04:29:17
【问题描述】:

我正在尝试在 Visual Studio 2013 中创建一个具有 CGAL 和 Boost(以及其他几个库)作为依赖项的 C++ 项目。我最好喜欢动态链接到这些库。另外,出于性能原因,我想链接到这些库的“发布”版本(而不是“调试”版本)。

从一个空的 C++ 项目开始,我添加了上述库的头文件的路径,如下图所示:

在链接器选项中,我添加了包含外部库的 DLL 和 lib 文件的目录。 (CGAL 目录包含 CGAL 编译的 DLL 文件以及 lib 文件)。

此时,我还没有添加单个“lib”文件“附加依赖项”对话框:

现在发生了一些奇怪的事情,我无法解释原因。如果我尝试按原样构建项目(在“调试”配置下),我会收到一个关于链接器无法找到 CGAL-vc120-mt-gd-4.7.libLNK1104 错误。我知道错误意味着我应该在“附加依赖项”对话框中添加lib 文件...

但是等等...什么...?!!
Visual Studio 如何知道如何自动链接到这个 lib 文件?!更糟糕的是,它怎么知道它需要库的“调试”版本? (带有gd 后缀)。另外,它怎么知道我用 VS2013 编译了 CGAL !!?? 起初,我认为该项目是从我系统中某处的某些预设属性表中继承属性。但我确信情况并非如此,因为即使是从头开始创建的项目也会显示这种行为。

我的主要问题是,您将如何强制 Visual Studio 链接到该库的“发布”版本? (例如CGAL-vc120-mt-4.7.lib

附带问题但相关:我什至链接到 DLL 文件吗?我如何确定我确实在做动态链接而不是静态链接?

【问题讨论】:

  • 有一个#pragma (comment:lib) support.microsoft.com/en-us/kb/153901 可以用来自动指定链接到哪个库。不知道这是否是您的方案正在做的事情,但这是不必使用项目设置指定库的一种方法。
  • 图书馆作者通常试图打败这种“我如何以无法诊断的方式使图书馆代码崩溃”的恶作剧。很明显,CGAL 作者采用了 Boost 使用的技术,它非常可靠。不得不处理成千上万的邮件列表问题所激发的智慧。使用 /NODEFAULTLIB 链接器选项的功能,而不是大众汽车,后果自负。
  • @HansPassant 感谢您的提示。那么CGAL作者怎么会提前知道lib文件应该是什么?!仅当我使用 VS2013 编译并启用 MT 时,我才会得到 CGAL-vc120-mt-gd-4.7.lib!他们会使用什么机制来强制使用特定的库版本?
  • 它们使用预定义的宏,即编译器根据编译选项设置的宏。像 _DLL 一样,在您使用 /MD 编译时定义。 “mt”表示多线程,与 /MT 编译选项无关。他们开的是不同的大众汽车。
  • 当然可以,但是你必须选择你不喜欢的编译设置。您只能希望发布构建库与您的代码的发布构建一起使用。调试这样的代码是,呃,字符构建。

标签: c++ visual-studio visual-studio-2013 linker


【解决方案1】:

这可能是由于 #pragma comment(lib) 机制而发生的 - 例如参见 What does "#pragma comment" mean?

这是编译器为链接器发出指令的一种方式,以便它可以根据编译器版本在库的多个版本之间做出决定。在这种情况下,这意味着它可以自动选择正确版本的库(debug vs release,vs2013 vs vs2015,MT vs MD,等等)。当您在 Additional Dependencies 中添加对库的显式引用时,它现在正在尝试查找两个文件。

因此,要解决此问题,请将其从 Additional Dependencies 中删除,然后让 VS 选择正确的库。如果您收到 LNK1104 错误,则表明链接库路径设置不正确,或者您没有它正在寻找的 CGAL 库文件。您可以在项目选项中增加链接器的详细设置,以获取有关正在发生的事情的更多详细信息。

【讨论】:

  • 这是否意味着文件中某处有一个#pragma comment 迫使VS 使用该特定的lib 文件?我如何找到导致它的文件(我尝试了 /VERBOSE 开关,但没有发生太多事情)。另外,从“附加依赖项”中删除什么?在问题中,我说我的“附加依赖项”是空的。
  • 我使用 grep 搜索了我正在使用的所有头文件(我的、CGAL 和 Boost 的),但在任何地方都没有找到任何与库相关的 #pragma comment
  • 在 boost 中定义在 config/auto_link.hpp: # pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT ".lib")
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 2011-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多