有没有办法(在 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。对于一般情况,目标不应该是确定链接和执行所需的最小库列表(正如我最初的问题以某种方式暗示的那样),而是真正为链接器提供必要的库,以便可以直接解析所有符号。
总结 Salgar 的回答,这些信息通常只能从所使用的库的文档中获得。此外,GCC 链接器标志-Wl,--as-needed
对于识别真正不需要的库很有用。]