C++ G++;动态图书馆链接问题

C++ G++;动态图书馆链接问题,c++,g++,dynamic-linking,C++,G++,Dynamic Linking,我试图将许多动态库链接到一个应用程序中,但在使用g++时遇到了问题 考虑: 利巴索 libB.so取决于libB.so libC.so依赖于libB.so 应用程序D直接依赖于libC.so 如果我尝试将应用程序D仅链接到libC.so,我会得到A和B中未解析的符号。我觉得编译器应该能够找到它,而当我使用英特尔编译器时,它确实找到了。然而,G++无法理解链接。我希望我的库和可执行文件只需要链接到它们直接需要的东西,而不是试图预测它们正在使用的库需要什么 当libA.so链接到静态库时,我也遇

我试图将许多动态库链接到一个应用程序中,但在使用g++时遇到了问题

考虑:

  • 利巴索
  • libB.so取决于libB.so
  • libC.so依赖于libB.so
  • 应用程序D直接依赖于libC.so
如果我尝试将应用程序D仅链接到libC.so,我会得到A和B中未解析的符号。我觉得编译器应该能够找到它,而当我使用英特尔编译器时,它确实找到了。然而,G++无法理解链接。我希望我的库和可执行文件只需要链接到它们直接需要的东西,而不是试图预测它们正在使用的库需要什么

当libA.so链接到静态库时,我也遇到了问题,当我试图编译可执行文件时,我从libA.so应该使用的静态库中得到了未解析的符号

我看到很多其他人问了这个问题和类似的问题,得到了各种各样的答案(),但答案都相当模糊,经常相互冲突,而且非常接近“继续卡车运输和RTFM”

我觉得链接顺序很重要。如何,我如何知道链接的顺序

更新


我相信正在发生的事情与libA类似。因此包含两个函数(AA和AB)。libB.so需要AA和libC.so需要AB。当libB.so被链接时,g++得到libA.so,发现只有AA被使用,并删除AB。然后当libC.so被链接进来时,g++发现libA.so已经被链接,并且没有重新访问它,导致AB未定义。我看过一些文档表明静态库是这样工作的,但是编译器会以同样的方式处理动态库吗?如果是这样的话,有办法解决吗?

您需要明确指定所有直接使用的库

在静态链接期间,不使用加载的.so的依赖项;链接主程序时,必须在主程序本身、命令行上指定的静态库或命令行上指定的共享库中找到所有符号

这就是你得到错误的地方

执行程序时,将加载动态库的依赖项,以便解析其他共享库中的引用。 当程序运行时,它实际上可能(动态地)链接到共享库的不同版本。此不同版本可能具有不同的依赖项,因此主程序不能依赖作为依赖项加载的附加库集

这就是静态链接器提前阻止您的原因。

(您尚未显示实际的链接器错误,或提供有关问题的足够信息,因此下面的部分是猜测…)

如果我尝试将应用程序D仅链接到libC.so,则会得到A和B中未解析的符号

链接可执行文件时,GNU链接器检查所有符号是否可用。您可以使用
--allow shlib undefined
(要告诉GCC将其传递给链接器,请使用
-Wl,--allow shlib undefined

最好不要使用该选项,但在这种情况下,链接器需要知道在哪里可以找到
libA.so
libB.so
,这样它就可以检查
libC.so
所需的符号。您可以使用链接器选项来实现这一点

使用ELF或SunOS时,一个共享库可能需要另一个。当“ld-shared”链接包含一个共享库作为输入文件时,就会发生这种情况

当链接器在执行非共享、不可重定位链接时遇到这种依赖关系时,它将自动尝试定位所需的共享库,并将其包含在链接中(如果未明确包含该库)。

因此,您应该能够通过使用
-Wl,-rpath link,.
通知链接器在当前目录(
)中查找库
libC来解决此问题。因此
取决于

我觉得链接顺序很重要。如何,我如何知道链接的顺序


是的,链接顺序很重要。您应该按照明显的顺序链接;-)如果某个文件
foo.cc
依赖于某个库,则稍后将该库放在链接器行中,这样在处理
foo.cc
后会找到该库,如果该库依赖于另一个库,则将该库放在更晚的位置,因此将在需要它的较早库之后进行处理。如果将库放在链接行的开头,则链接器没有任何未解析的符号可供查找,因此不需要链接到该库。

如果libC直接引用libA中的符号,则libC可能应该直接链接到libA。“但是,G++无法识别链接。”你指的是链接器,而不是G++“g++获取libA.so,发现只使用了AA,并删除了AB”再说一遍,g++与之无关,链接器会这样做,但不,它对动态库不起作用您使用的是哪个版本的binutils?您得到的错误是什么?它是否提到
-rpath link
?我的链接器错误大致如下”libX.so:undefined reference/symbol fooBar”,其中“fooBar”来自libX.so链接到的库之一。这是标准的“您没有使用正在使用的函数链接到库”“链接错误。libX.so正确链接,ldd显示它引用了所需的库,但我从libX.so生成的可执行文件会生成链接错误。是的,可执行文件直接链接到它使用的所有东西。问题是当可执行文件链接到B,B使用A,但可执行文件不使用A,因此不会直接链接到它。你能澄清-rpath和-rpath链接之间的区别吗?而且,看起来这两个函数都只是指定了动态库的运行时搜索路径。这和setti有什么不同