如何避免在两个使用相同静态库的静态库中出现“LNK2005已定义错误”?

4

情况:

  • 静态库LIB1,从源代码编译并链接为lib1.lib(使用/MD)。 使用库LIB2,并在其中包含来自lib2.lib的对象。
  • 静态库LIB2也是用/MD编译的。
  • EXE间接依赖于这两个库。

在MSVC 15.9.19上链接此EXE的结果:出现很多LNK2005错误,例如:

lib2.lib: error LNK2005: "function <funcsig> already defined in lib1.lib"

我经常会收到类似这样的警告信息:

lib1.lib: warning LNK4099: PDB 'lib2.pdb' was not found with 'lib1.lib' or at '<path>'; linking object as if no debug info

问题: 为什么链接器没有合并重复定义? 我如何诊断这个问题的确切原因?
谢谢!
更新: 错误与标准库无关。它们涉及Google Protobuf函数。LIB2是Google的libprotobuf.lib。LIB1也是Google的OR-Tools库,使用Protobuf。但我们也使用Protobuf,因此出现了冲突!

2
看起来LIB1做了一些不应该做的假设。它要么不应该与另一个静态库链接,要么不应该从该库中导出任何符号。如果使用/NODEFAULTLIB:LIB2链接器选项会发生什么? - 1201ProgramAlarm
/ FORCE:MULTIPLE 有帮助吗? https://learn.microsoft.com/en-us/cpp/build/reference/force-force-file-output?view=vs-2019 - srinivirt
告诉链接器使用除默认库之外的库,可以在命令行上指定要使用的库,并使用 /NODEFAULTLIB 选项禁用默认库。在 IDE 中,添加对项目的引用以指定要使用的库,然后打开项目的属性页对话框,在链接器、输入属性页中,设置“忽略所有默认库”或“忽略特定默认库”属性以禁用默认库。 - Nagappa
知道“funcsig”的含义将会有所帮助。具体来说,它是您代码中的符号还是来自 CRT(C-Run Time 库)?如果它是 CRT 函数,则很可能您没有正确设置 /MD 标志。如果不是,则您的库之间存在重复的符号。最明显的发生这种情况的方式是在头文件中出现非内联函数。 - Tiger4Hire
@1201ProgramAlarm: /NODEFAULTLIB:LIB2没有帮助,仍然出现相同的错误信息。 - Alex Jenter
显示剩余3条评论
1个回答

1

这个 MSDN链接 几乎肯定会有所帮助。

正如你所说,这些不是标准的C/C++函数,你可以忽略关于混合调试和发布代码的部分。不幸的是,这仍然给你留下了很多可能的原因。这个错误是一个好的排除对象。

如果您在使用/clr选项时同时使用静态库和动态库,则可能会出现此错误。

如果您在编译时查看命令行选项,可以通过打开详细模式或检查每个文件的属性来实现。

一旦排除了这种情况,所有其他原因都是你字面上声明了相同的东西(函数/变量)两次。最可能发生这种情况的方法是将某些东西(如函数)放在头文件中,该头文件由多个模块文件包含。不看代码进行诊断很难。您必须选择其中一个错误,并选择名称的一部分,该部分不是mangled,基本上是可读的。然后,您需要检查它的声明位置,并查看是否在标题中。如果不是,则必须从源文件包含非标题。找到文件包含的快速(和肮脏)方法是向文件添加#pragma message,然后逐个重新编译文件以查看何时打印出来。要了解其被包含的原因,请使用show includes
如果符号是从头文件中声明的,您必须通过将其前向声明来修复它。 如果您不知道如何操作,我建议您提出一个新问题,例如“如何进行前向声明?”。这应该能够很快得到答案。
希望这可以帮助您。

这是一个很好的答案,谢谢。不幸的是,它对我帮助不大。1)我不使用/clr选项。2)如果Protobuf的头文件违反了ODR,那么该库将几乎无法使用,但它是Google本身的一个非常受欢迎的库。基本上,错误来自于Or-Tools库(LIB1)不应该重新导出Protobuf的符号,但它确实这样做了。我希望有人能给出如何避免这种情况的建议。 - Alex Jenter
一个库是对象文件(存档)的容器。对象文件来自模块文件。如果您正在使用静态链接,那么您必须在模块中创建重复的函数。DLL“导出”符号。它将动态加载的符号(未链接)与具有相同名称的静态函数镜像。它们加载动态函数并调用它们。(这称为thunk'ing)。您是否意外地使用了DLL。请参见此处 https://dev59.com/KVTTa4cB1Zd3GeqPsXOw - Tiger4Hire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接