【问题标题】:g++ linking order dependency when linking c code to c++ code将c代码链接到c ++代码时的g ++链接顺序依赖性
【发布时间】:2011-03-22 18:15:38
【问题描述】:

在今天之前,我一直认为在链接阶段将对象和库传递给 g++ 的顺序并不重要。然后,今天,我尝试从 c++ 代码链接到 c 代码。我将所有 C 标头包装在一个 extern "C" 块中,但链接器仍然难以找到我知道在 C 对象档案中的符号。

困惑,我创建了一个相对简单的示例来隔离链接错误,但令我惊讶的是,更简单的示例链接没有任何问题。

经过一些尝试和错误,我发现通过模拟简单示例中使用的链接模式,我可以得到主代码来链接 OK。该模式首先是对象代码,其次是对象档案,例如:

g++ -o serverCpp serverCpp.o algoC.o libcrypto.a

谁能解释为什么会这样?我在链接普通c++代码时从未见过这个问题。

【问题讨论】:

标签: c++ c g++ linker


【解决方案1】:

您指定目标文件和库的顺序在 GCC 中非常重要 - 如果您在过上迷人的生活之前还没有被这一点困扰的话。链接器按照符号出现的顺序搜索符号,因此如果您有一个包含对库函数的调用的源文件,则需要将它放在库之前,否则链接器将不知道它必须解析它。库的复杂使用可能意味着您必须多次指定库,这对于正确处理是一件非常痛苦的事情。

【讨论】:

  • 相信我,我没有:-),有没有关于这个属性的文档?
  • 我也一直认为链接顺序很关键;在您猜测顺序错误之前,也很难弄清楚为什么会发生链接错误...
  • @Gearoid 万一您对链接器感兴趣,请查看iecc.com/linker
  • @PP 没有什么比链接器错误消息更让我害怕的了。
  • +1 表示“多次指定库”。关键,关键,关键!
【解决方案2】:

传递给 gcc/g++ 的库顺序确实很重要。如果A 依赖于B,则必须首先列出 A。原因是它优化了没有被引用的符号,所以如果它首先看到库B,并且当时没有人引用它,那么它根本不会链接任何东西。

【讨论】:

    【解决方案3】:

    静态库是分组到存档中的对象文件的集合。当链接它时,链接器只选择它需要的对象来解析任何当前未定义的符号。由于对象是按照命令行中给定的顺序链接的,因此仅当库位于依赖于它的所有对象之后时,才会包含库中的对象。

    所以链接顺序很重要;如果你打算使用静态库,那么你需要小心跟踪依赖关系,不要在库之间引入循环依赖。

    【讨论】:

    • 循环依赖没问题——这只是意味着你需要有一个像“a.o b.o a.o”这样的链接行。
    • @caf: 如果第二次包含a 的额外对象依赖于b 中尚未包含的对象,那么这还不够好;您需要在最后再次添加b。这反过来可能会引入更多对a 的依赖。所以循环依赖并不是真的“OK”,它们很少会病态到需要不止一次重复。
    【解决方案4】:

    您可以使用--start-group archives --end-group 并编写 2 个依赖库而不是 archives

    gcc main.o -L. -Wl,--start-group -lobj_A -lobj_b -Wl,--end-group
    

    【讨论】:

      猜你喜欢
      • 2010-11-03
      • 1970-01-01
      • 2013-07-12
      • 1970-01-01
      • 2015-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多