我如何知道链接哪些库?

有没有办法(在Linux中)确定我必须链接C / C ++程序的库? 即使在程序启动时未检测到未定义符号的情况下,我也不想错过图书馆。 另外,我想避免不必要的依赖关系。

我一般提出了这个问题,但这里是一个特殊的,不重要的例子:直到最近,我还以为我需要链接到使用Boost.Python开发的Python模块的libpython。 但是,这不是真的:用Boost.Python编写一个模块; 它甚至可能使用Python C API的函数,而不仅仅是Boost.Python。 链接到libboost_python就足够了! 这根本不明显 - 至少我没有发现它的记录,并且有Boost.Python模块,它们不必要地链接到libpython。 此外,由于ldd报告libboost_python.so没有列出libpython作为依赖项,因此很难检测到。 (我相信Python库是在这个实例中动态加载的。)

[ 稍后添加:这是独立于Boost.Python。 另外,如果使用低级别的Python C API,则可以编译Python模块,而不是链接到libpython,它将起作用。 但是,请参阅下面的评论和答案,指出应该与libpython链接。]

那么,我怎么能系统地发现不必要的链接,而不是使用反复试验? 不仅是这个例子,一个好的一般程序是什么?

[ 稍后添加:这是我从我的问题的评论中学到的。 当我发布这个问题时,下面的事实并不清楚,所以我现在拼出来,为将来访问这些讨论的人带来好处,即使这些事情对于有帮助的评论者来说也是显而易见的。 (谢谢!)

解析符号在Linux中以传递的方式工作(正如用户MvG和毫微微指出的那样)。 假设程序A需要解析来自libB和libC的符号。 进一步假设A与libB链接,libB与libC链接。 然后,即使它不直接引用libC,也可以加载并执行A.

然而,正如评论者指出的那样,依靠这种传递性是不好的做法。 在用C / C ++编写的Python模块的情况下,这意味着应该链接到libpython。 对于一般情况,目标不应该是识别链接和执行所需的最小库列表 - 因为我的原始问题不知何故受到影响 - 但确实为连接器提供了必要的库,以便所有符号都可以直接解析。

总结Salgar的回答,这些信息通常只能从所用库的文档中获得。 此外,GCC链接程序标志-Wl,--as-needed用于识别真正没有必要的库。]


没有办法神奇地知道要包含哪些库,就像没有办法神奇地知道哪些头包含在一起。

可能有10个不同的库,都具有相同名称的功能,都做完全不同的事情。 由您决定要使用哪一个。

通常情况并非如此,但它提供了一个示范点。

通常,如果您使用增强库或其他类似的库,他们的文档会让您知道需要链接哪个库。

就像上面提到的那个人一样,你可以过度包含和使用标志 - 需要,但很多人都会遇到问题,一般来说,当你连接到一个库时,它会在启动时被拉入,并且来自该库的所有全局变量被初始化。 无论您是否需要这些全局变量,链接器都能解决这个问题。

总之,答案通常是阅读文档。 或者编译代码并查看出现哪些链接器错误,然后从中找出需要的库。


没有任何/平凡/方法,但通过使用像CMake或AutoConf这样的构建管理工具,您可以让自己变得更容易。


当您构建Boost时,您可以选择编译静态或动态版本的库。 我已经建立了提升已经有一段时间了,但是如果我回想一下,如果你只是做简单的构建,它就构建了两种风格。

这包括在:

  • http://www.boost.org/doc/libs/1_53_0/more/getting_started/unix-variants.html#library-naming
  • 关于boost.python,静态或动态库链接之间的选项记录在这里:

  • http://www.boost.org/doc/libs/1_53_0/libs/python/doc/building.html#naming
  • 动态库是最安全和最通用的选择:

  • 所有使用特定工具集构建的扩展模块都使用库代码的一个副本。库包含一个类型转换注册表。 因为一个注册表是在所有扩展模块之间共享的,所以在一个动态加载的扩展模块中暴露给Python的类的实例可以被传递给在另一个这样的模块中公开的函数。
  • 在以下任何情况下使用静态Boost.Python库可能是适当的:

  • 您正在扩展python,并且暴露在动态加载的扩展模块中的类型不需要被任何其他Boost.Python扩展模块使用,并且您不关心核心库代码是否与其中重复。

  • 您正在将Python嵌入到您的应用程序中,并且:

  • 您的目标是除MacOS或AIX以外的Unix变体操作系统,其中动态加载的扩展模块可以“查看”作为可执行文件一部分的Boost.Python库符号。

  • 或者,您将一些Boost.Python扩展模块静态链接到您的应用程序中,并且您不关心任何动态加载的Boost.Python扩展模块是否能够使用静态链接扩展模块公开的类型(反之亦然)。

  • 所以,理所当然,这并不能解释你如何知道在一般意义上与什么关联。 只是一个特定的情况。

    我认为,关于boost.python的工作方式以及人们在链接方面评论的不同体验的混淆可能会让您看到至少透过这个镜头更有意义。

    链接地址: http://www.djcxy.com/p/70643.html

    上一篇: How do I know which libraries to link against?

    下一篇: NoClassDefFoundError in web application running on Tomcat 7