【发布时间】:2011-09-20 05:17:32
【问题描述】:
我公司最近从 VS2005 升级到 VS2010。我们有一个庞大的项目,它使用了很多静态链接到 exe 中的模块。但在 VS2010 中的链接似乎存在一些问题。
为了解释我们的问题,我们构建了一个最小的示例项目,其组成如下图所示:
有一个应用程序使用库 A 中的一个函数。库 A 调用每个库 B 和库 C 的一个函数。这两个库调用库 D 提供的一个函数。
对于 Framework and References 下的 Exe 1,我们将所有内容都设置为 false,除了 Link Library Dependencies 是设置为真。添加的唯一参考是链接到库 A。对于每个库,所有设置都设置为 false。库 A 仅获得对 B 和 C 的引用,而这两个库仅获得对 D 的引用。 库 D 没有引用。
在构建应用程序时,它可以正常工作。应用程序注意到库 A 正在使用库 B,而 C 正在使用库 D,因此它知道它也必须链接这些库。库链接到 exe 没有问题。
现在我们在库 D 中进行一些更改。只是一点点不同,只有一个字母。现在我们尝试再次构建应用程序,它注意到更改并重新编译 library D,但是:它不再链接到它。结果是 library B 和 C 中的链接错误,因为它们使用 library D。我们必须先运行Rebuild,以强制完成构建,然后然后再次链接所有内容。
对于最小示例和我们的主要项目都会发生这种情况。当然,我们可以将每个库添加为 exe 的附加依赖项,但如果它能够像第一次构建项目时那样工作并在代码更改后继续工作,那就太好了。我们注意到,当将 Use Library Dependency Inputs 设置为 true 时,它会再次起作用,但是它不会链接 *.lib 文件而是链接 *.obj 文件当然不是我们想要的。
有没有人有过类似的经历或者有没有人解决这个问题?这是 VS2010 的错误行为吗?
TIA。
p.s.:所有库和可执行文件都是原生 C++。
编辑:(解决方法取自this site)
在%ProgramsFile%\MSBuild\Microsoft.cpp\v4.0\Microsoft.CPPBuild.Targets文件中有一行
<Target Name="GetResolvedLinkLibs" Returns="@(LibFullPath)" DependsOnTargets="$(CommonBuildOnlyTargets)">
如果您将该行更改为
<Target Name="GetResolvedLinkLibs" Returns="@(LibFullPath)" DependsOnTargets="$(CommonBuildOnlyTargets);ResolvedLinkLib">
链接工作正常,所有需要的库都被隐式链接到。链接器输出不仅显示 lib_a.lib,还显示所有其他链接的库、lib_b、lib_c、lib_d,而无需手动将它们作为依赖项添加到 exe。
这似乎更像是一种解决方法而不是解决方案,也许有一种适当的方法来实现隐式链接。
【问题讨论】:
标签: c++ visual-studio visual-studio-2010 linker static-linking