最近更新了从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 的导入不再被引入,让我想,库配置可能是问题所在。 我使用命令行参数来调试和发布库的构建,并将它们并排比较,以找出配置的差异。 我设法将问题指向优化设置(在优化选项卡上):
我的问题是,这对于调试来说是非常直观的,因为编译器会优化太多东西,可能会使调试更难。
在发布之前,我到处寻找,并在我们的主项目的Linker-&gt;优化页面中查看,参考选项设置为是(/ OPT:REF) ,这应该避免链接未使用的代码,但在我看来,VS2015在调试版本上完全忽略了这个设置。
答案 0 :(得分:1)
经过一番搜索后发现了这篇文章:http://www.drdobbs.com/cpp/the-most-underused-compiler-switches-in/240166599?pgno=6。
事实证明,在 libA 中设置选项 / Gy(启用功能级别链接)不再导致导入未使用的API