我有一组静态编译的库,库之间具有相当深的依赖性.例如,可执行文件X使用库A和B,A使用库C,B使用库C和D:
X -> A A -> C X -> B B -> C B -> D
当我将X与A和B链接时,如果C和D也没有添加到库列表中,我不想得到错误 - A和B在内部使用这些库的事实是X不应该需要的实现细节要了解.此外,当在依赖关系树中的任何位置添加新依赖项时,必须重新配置使用A或B的任何程序的项目文件.对于深度依赖关系树,所需库的列表可能变得非常长且难以维护.
所以,我正在使用A项目中Librarian部分的"Additional Dependencies"设置,添加C.lib.在B项目的同一部分,我添加了C.lib和D.lib.这样做的结果是图书馆员将C.lib捆绑成A.lib,将C.lib和D.lib捆绑成B.lib.
但是,当我链接X时,A.lib和B.lib都包含它们自己的C.lib副本.这导致了大量的警告
A.lib(c.obj):警告LNK4006"符号"(_symbol)已在B.lib(c.obj)中定义; 忽略第二个定义.
如何在不收到警告的情况下完成此操作?有没有办法简单地禁用警告,还是有更好的方法?
编辑:我看到不止一个答案表明,由于缺乏更好的替代方案,我只是禁用警告.嗯,这是问题的一部分:我甚至不知道如何禁用它!
据我所知,您无法禁用链接器警告.但是,您可以使用链接器的命令行参数来忽略其中一些,例如./忽略:4006
将它放在链接器 - >命令行设置下的项目属性中(不记得确切的位置).
另请阅读:
链接/忽略
MSDN论坛 - 隐藏LNK警告
Wacek
更新如果您可以在单个解决方案中构建所有涉及的项目,请尝试:
将所有项目放在一个sln中.
从项目的链接器或库管理器属性中删除对静态库的所有引用.
解决方案资源管理器中的每个项目的上下文菜单中都有"项目依赖项..."选项.用它来定义项目之间的依赖关系.
它应该工作.它不会使我之前说过的任何内容失效,构建C/C++程序的基本模型保持不变.VS(至少2005和更新版本)非常智能,可以将所有需要的静态库添加到链接器命令行.您可以在项目属性中看到它.
当然,如果您需要使用已编译的静态库,此方法将无济于事.然后你需要将它们全部添加到直接或间接使用它们的exe或dll项目中.
我认为你无能为力.您应该从静态库项目中删除对其他静态库的引用,并添加所有需要的静态库项目作为exe或dll项目的依赖项.您将不得不忍受任何包含A.lib或B.lib的项目都需要包含C.lib的事实.
作为替代方案,您可以将库转换为dll,从而提供更丰富的模型.
静态编译的库根本不是具有依赖性信息等的真实库,如dll.了解在构建它们时,您真的不需要提供它们所依赖的库吗?标题就是所需要的.看到?你甚至不能说静态库依赖于某些东西.
静态库只是已编译和尚未链接的目标代码的归档.它并不完整.每个目标文件都是单独编译的,并且在库中保持独立的实体.构建exe或dll时会发生链接.那是你需要提供所有目标代码的时候.这就是所有符号和依赖性解决发生的时候.
如果将其他静态库添加到静态库依赖项,则库管理器将简单地将所有代码复制到一起.然后,在构建exe时,链接器会给你很多关于重复符号的警告.您可能能够阻止这些警告(我不知道如何),但要小心.它可能隐藏真正的问题,例如具有不同定义的真实重复符号.如果您在库中定义了静态数据,那么它可能无法工作.