Visual C强制未使用的导入,由库拉入
最近更新了一个从VisualStudio2010到2015的项目,我们遇到了一个奇怪的链接时间问题 我们为amd64和x86以及调试和发布模式构建项目。 该项目有两个依赖项,我们称它们为libA和libB。 我们有一些定制的编译后脚本,可以对二进制文件进行一些验证(比如检查NX和SEH标志等)。 使用此脚本,我们还将验证导入的DLL及其导入的函数,以尽可能减少静态导入,并尝试通过动态加载解决额外的导入(为了向后兼容) 迁移之后,我们设法在每种可能的配置中构建所有内容,但在调试模式下(仅在调试模式下),由于libA中存在代码,因此生成的二进制文件会引入一些实际上未使用的导入(我们称之为dllA),因此,我们不希望在场。 libB没有引入任何问题-尽管它是一个非常简单的库 libA之所以引入这些导入,是因为它是一个多用途库,被其他一些项目使用,并且它有一些代码,从dllA调用函数,但在我们的项目中,我们根本不调用那些dllA导出调用函数。 我还用IDA反汇编了dll,发现这些函数位于二进制文件中,与二进制文件的其余代码完全断开连接-它们根本没有被引用 经过一番搜索,并试图将libA的发行版链接到我们项目的调试版本,我发现从dllA的导入不再被拉入,这让我想到,库配置可能是个问题。 我获取了库的debug和release构建的命令行参数,并将它们并排进行比较,以找出配置上的差异。 我设法将问题锁定到优化设置(在“优化”选项卡上):Visual C强制未使用的导入,由库拉入,c,visual-studio-2010,visual-studio-2015,linker,dllimport,C,Visual Studio 2010,Visual Studio 2015,Linker,Dllimport,最近更新了一个从VisualStudio2010到2015的项目,我们遇到了一个奇怪的链接时间问题 我们为amd64和x86以及调试和发布模式构建项目。 该项目有两个依赖项,我们称它们为libA和libB。 我们有一些定制的编译后脚本,可以对二进制文件进行一些验证(比如检查NX和SEH标志等)。 使用此脚本,我们还将验证导入的DLL及其导入的函数,以尽可能减少静态导入,并尝试通过动态加载解决额外的导入(为了向后兼容) 迁移之后,我们设法在每种可能的配置中构建所有内容,但在调试模式下(仅在调试模式
- 对于调试模式,默认设置为禁用(/Od)
- 对于释放模式,设置为最大速度(/O2)
- 设置最大化速度(/O2)用于调试模式可以解决问题-不再导入dllA
在发布之前,我到处查看,也查看了我们主要项目的Linker->Optimization页面,并且References选项设置为Yes(/OPT:REF),这应该可以避免链接未使用的代码,但在我看来,VS2015完全忽略了调试版本上的此设置。经过一些搜索后,发现本文:
事实证明,在libA中设置选项/Gy(启用函数级链接)不再会导致导入未使用的API重复注释