繁体   English   中英

我如何知道要链接哪些库?

[英]How do I know which libraries to link against?

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

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

[ 后来添加:这与Boost.Python无关。 此外,如果使用低级Python C API,则可以编译Python模块,而不是与libpython链接,它将起作用。 但是,请参阅下面的评论和答案,说明应该链接到libpython

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

[ 后来补充:这是我从评论中学到的问题。 当我发布这个问题时,下面的事实对我来说并不清楚,所以我现在将它们拼出来,以便将来访问此讨论的人受益,即使这些事情对于有用的评论者来说是显而易见的。 (谢谢!)

解析符号在Linux中以传递方式工作(如用户MvG和millimoose所指出的)。 假设程序A需要解析来自libBlibC的符号。 进一步假设A是针对libB相连,libB是对的libC链接。 然后可以加载即使它没有直接提及到libc执行。

然而,正如评论者指出的那样,依靠这种传递性是不好的做法。 对于用C / C ++编写的Python模块,这意味着应该链接libpython 对于一般情况下,我们的目标应该是确定的链接和执行,为我的一部开拓创新的问题在某种程度上暗示,但真正提供链接必要的库,以便所有的符号可以直接解决需要的库的最小列表。

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

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

可能有10个不同的库,它们都具有相同名称的功能,所有这些都完全不同。 由您决定要使用哪一个。

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

通常,如果您使用的是boost库或其他类似的库,那么他们的文档会告诉您需要链接哪个库。

正如上面所说的那样,你可以过度包含和使用标志--as-needed,但很多人都有问题,因为通常当你链接到一个库时,它会在启动时被拉入并且来自该库的所有全局变量初始化。 是否需要这些全局变量对于链接器来说可能是一件令人困惑的事情。

简而言之,答案通常是阅读文档。 或者编译代码并查看您获得的链接器错误,然后从那里开始工作以确定您需要哪些库。

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

构建Boost时,您可以选择构建已编译的库的静态或动态版本。 自从我构建了boost之后已经有一段时间了,但是如果我记得它可以构建两种风格,如果你只是简单的构建。

这包含在:

关于boost.python,这里记录了静态或动态库链接之间的选项:

动态库是最安全,最通用的选择:

  • 使用给定工具集构建的所有扩展模块都使用库代码的单个副本。该库包含类型转换注册表。 因为一个注册表在所有扩展模块之间共享,所以在一个动态加载的扩展模块中暴露给Python的类的实例可以传递给在另一个这样的模块中公开的函数。

在以下任何一种情况下使用静态Boost.Python库可能是合适的:

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

  • 您正在应用程序中嵌入python并且:

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

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

所以,如果被授予,这并不能解释你如何知道通用意义上的链接。 只是那个具体情况。

我认为关于boost.python如何工作以及人们在链接方面评论的不同体验的困惑可能会让你更有意义,至少你看一下这个镜头。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM