Visual C强制使用未使用的导入,由库

时间:2017-08-03 08:44:30

标签: c visual-studio-2010 visual-studio-2015 linker dllimport

最近更新了从Visual Studio 2010到2015的项目,我们遇到了一个奇怪的链接时问题。

我们为amd64和x86以及调试和发布模式构建我们的项目。 该项目有2个依赖项,我们称之为 libA libB 。 我们有一些自定义的后期构建脚本,它们对二进制文件进行一些验证(例如检查NX和SEH标志等)。 使用此脚本,我们还验证导入的DLL及其导入的函数,以尽可能少地保持静态导入,并尝试通过动态负载解决额外的导入(为了向后兼容)。

迁移之后,我们设法在每个可能的配置中构建所有内容,但是在 DEBUG 模式下(并且仅在DEBUG模式下)生成的二进制文件 - 由于 libA中存在的代码 - 拉入一些进口 - 我们称之为 dllA - 实际上没有使用,因此不希望出现。 libB 没有引入任何问题 - 尽管它是一个非常简单的库。

libA 拉动这些导入的原因是因为它是一个多用途库,被其他一些项目使用,并且它有一些代码,从 dllA <调用函数/ strong>,但在我们的项目中,我们根本不会调用那些dllA-export-calling-functions。 我还用IDA反汇编了dll,发现这些函数位于二进制文件中,与二进制文件中的其余代码完全断开 - 根本没有引用它们。

经过一番搜索,并试图将 RELAASE 版本的 libA 链接到我们项目的 DEBUG 版本后,我发现了,从 dllA 的导入不再被引入,让我想,库配置可能是问题所在。 我使用命令行参数来调试和发布库的构建,并将它们并排比较,以找出配置的差异。 我设法将问题指向优化设置(在优化选项卡上):

  • 对于DEBUG模式,默认设置为Disabled( / Od
  • 对于RELEASE模式,它设置为最大化速度( / O2
  • DEBUG 模式设置最大化速度(/ O2)可以解决问题 - 不再导入dllA

我的问题是,这对于调试来说是非常直观的,因为编译器会优化太多东西,可能会使调试更难。

在发布之前,我到处寻找,并在我们的主项目的Linker-&gt;优化页面中查看,参考选项设置为是(/ OPT:REF) ,这应该避免链接未使用的代码,但在我看来,VS2015在调试版本上完全忽略了这个设置。

1 个答案:

答案 0 :(得分:1)

经过一番搜索后发现了这篇文章:http://www.drdobbs.com/cpp/the-most-underused-compiler-switches-in/240166599?pgno=6

事实证明,在 libA 中设置选项 / Gy(启用功能级别链接)不再导致导入未使用的API