【问题标题】:Are references across .o files resolved when building a static library?构建静态库时是否解决了跨 .o 文件的引用?
【发布时间】:2019-06-12 00:06:38
【问题描述】:

例如,假设我构建了一个库 a.lib,它有两个文件:foo.c 和 bar.c。 foo.c 调用了 bar.c 中定义的函数void bar()

现在假设我要创建一个可执行文件,它有两个文件:main.c 和 bar.c。此 bar.c 还定义了 void bar(),但实现不同。

当我将可执行文件与 a.lib 链接时,可执行文件将调用哪个void bar()

【问题讨论】:

  • 请发布您的代码以及您尝试做的事情

标签: c linker


【解决方案1】:

让我们假设:

  1. 库是libfoobar.a(或libfoobar.lib),位于目录./lib
  2. 库文件foo.c 定义foo()foo() 调用bar()
  3. 库文件bar.c 定义bar()
  4. 库源文件不在当前目录中。
  5. 程序文件bar.c 还定义了bar() — 一个不同的实现。
  6. 程序文件main.c同时调用foo()bar()
  7. 您的链接命令行如下所示:

    cc -o program main.o bar.o -L ./lib -lfoobar
    

然后:

  • 该程序将包含来自程序文件bar.cbar()(因为它已明确包含在命令行中,位于库之前)。
  • 程序将包含库文件foo.c 中的foo(),但它调用的bar() 将是程序文件bar.c 中的@,而不是库中的@。

如果涉及更多符号,使得库foo.c 调用仅在库bar.c 中可用的函数(程序bar.c 没有实现所有这些函数),那么链接将失败,因为program 包含程序的bar.c(无条件),但它也需要库的bar.c,但这会给您函数bar() 的双重定义——这是一个错误。

曲折可能会变得严重。简单的经验法则——不要这样做。也就是说,不要让程序的bar.c 提供库的bar.c 中也可用的符号。如果必须,并且涉及其他切入点,那么您必须更加努力。

不要将库放在目标文件之前;那么您将因bar() 双重定义而失败。库跟踪链接列表中的目标文件。不过,您确实需要以正确的顺序获取多个(静态)库。或者使用特殊选项使加载器重新扫描库等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-11
    • 2018-10-05
    • 1970-01-01
    • 2011-01-10
    相关资源
    最近更新 更多