【问题标题】:Can a dynamic library depend on a static library in C and vice-versa?动态库能否依赖于 C 中的静态库,反之亦然?
【发布时间】:2019-05-04 11:49:22
【问题描述】:

我试图了解 C 中的静态库和共享对象。我试图了解一种类型的库是否可以依赖于其他类型。

考虑一个场景:

libA.so 有一个函数 foo_A_dyn():

libA.so ---> foo_A_dyn()

foo_A_dyn() 使用函数 foo_B_static() 定义在 libB.a 中,这是一个静态库。

libB.a ---> foo_B_static()

我通过以下方式构建了我的库:

gcc -c foo_B.c -o foo_B.o
ar -cvq libB.a foo_B.o

gcc -fPIC -c foo_A.c -o foo_A.o
gcc -shared libA.so foo_A.o -I.

gcc main.c -lA -lB -L. -I. -o EXE

注意:main.c 调用 foo_A_dyn() 而不是直接调用 foo_B_static()。

现在,当我尝试构建可执行 EXE 时,我收到错误“未定义对 foo_B_static 的引用”。

我认为这个错误似乎是真实的,但我无法解读其背后的基本原理并将其付诸实践。

有人可以帮忙吗?

【问题讨论】:

  • 我们能否推断出main.c 包含对foo_A_dyn() 的引用,但不包含libB.a 中包含foo_B_static().o 文件中的任何符号?如果您在main.c 中的代码明确引用foo_B_static(),就没有问题。如果是我,我会将-L. 选项放在使用它的-lA-lB 选项之前,但我不确定在这种情况下它是否重要(不过我认为它通常是有的——但是我愿意证明我在特定系统上的错误)。
  • 我的印象是共享对象可以依赖其他共享对象,但不能涉及静态归档(所以共享对象不能依赖静态归档,静态归档不能依赖共享对象,并且一个静态存档不能依赖另一个)——都是在“自动链接或加载依赖的文件”的意义上。不过,我没有手册页可以引用。链接器是否有可能使用与您预期不同的libB.solibB.a
  • @JonathanLeffler 我已根据您的 cmets 编辑了我的问题。我将尝试不同的库依赖组合,并很快更新我的观察结果。

标签: c gcc shared-libraries


【解决方案1】:

来自gcc link options

-图书馆
-l 库
...
在命令中编写此选项的位置有所不同;链接器按照指定的顺序搜索和处理库和目标文件。因此,“foo.o -lz bar.o”在文件 foo.o 之后但在 bar.o 之前搜索库“z”。如果 bar.o 引用了 ‘z’ 中的函数,这些函数可能不会被加载。

试试:

gcc main.c -lB -lA -L. -I. -o EXE

【讨论】:

  • @Kamil 正如您正确指出的那样,这是一个订购问题。非常感谢您指出这一点。由于此处的字符数限制,我正在更新我的观察结果作为问题的答案,而不是在评论中。
【解决方案2】:

这是链接器正在做的事情。当我们链接我们的可执行文件(上面的“EXE”)时,它有一些未解析的符号(函数和其他东西)。它将按顺序查看后面的库列表,尝试解析未解析的符号。一路上,它发现一些符号是由 libB.so 提供的,所以它注意到它们现在由这个库解析。在通过 libB.so 时,它会找到一些未解析的符号,并尝试通过查找后面的库来解析它们。

当我们订购库时:

gcc main.c -lA -lB -L. -I. -o EXE

链接器无法将 libB 中使用的符号定义查找到 libA 中。原因可能是向后引用不可用。

我也想通了:

  1. 共享对象可以依赖于静态存档,

  2. 静态存档可以依赖于共享对象,并且

  3. 一个静态存档可以依赖于另一个静态存档

如果我在某个地方出错了,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多