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

时间:2013-04-04 04:21:29

标签: c++ c

有没有办法(在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 需要解析来自 libB libC 的符号。进一步假设 A libB 相关联, libB libC 相关联。然后 A 即使没有直接引用 libC 也可以加载和执行。

然而,正如评论者指出的那样,依靠这种传递性是不好的做法。对于用C / C ++编写的Python模块,这意味着应该链接 libpython 。对于一般情况,目标应该来识别链接和执行所需的最小库列表 - 正如我的orignal问题以某种方式暗示 - 但实际上是为链接器提供必要的库以便< em>所有符号可以直接解析

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

3 个答案:

答案 0 :(得分:4)

没有办法神奇地知道要包含哪些库,就像没有办法神奇地知道要包含哪些标题一样。

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

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

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

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

这包括在:

关于boost.python,静态或动态库链接之间的选项在此处记录:

        

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

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

在任何版本中使用静态Boost.Python库可能是合适的   以下案件:

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

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

         
        
    • 您的目标是除MacOS或AIX之外的Unix变体操作系统   动态加载的扩展模块可以“看到”Boost.Python   属于可执行文件的库符号。

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

    •   
  •   

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

我觉得有关boost.python如何的困惑 工作和人们评论的不同经历 当你仔细观察这个镜头时,链接可能会更有意义。