我有一个共享库,它试图提供一个标准化的接口(interface),基本上是一个函数列表。其中一些功能已经由另一个共享库提供。所以我可以只编写附加函数并要求用户链接到两个库,即让他这样做:
g++ foo.c -lmine -lother
但是,为了让用户更轻松,我不想那样做。 (考虑到我所处的情况,这比在某些脚本中添加一个标志要复杂得多。)我希望用户仅链接到我的库并从其他库中获取函数。
在 Windows 中,我可以使用 DLL 转发器并简单地列出我想要重新导出的函数。在 MacOS 中,我可以使用 --reexport_library
链接器选项让我的库假装包含另一个库。如果我不介意创建其他库的完整副本并且有一个静态版本,我可以使用 --whole-archive
将其全部拉入我的库。
但是在 Linux 中有什么方法可以为我的库的导出表提供一个条目,上面写着“这个函数在那边的另一个库中”?
或者,我是否可以对我的库做任何事情,以便在将它提供给链接器时,链接器会说,“哦,我也需要引入另一个库”? --rpath-link
选项的文档表明这应该可以正常工作,但事实并非如此。当然,libtool 会执行此操作,但 libtool 不是一个选项。
我当然可以做的只是用这些函数的小 stub 填充我的库,但我宁愿不这样做。如果必须以正确的顺序重命名以便链接器在正确的时间选择正确的版本,那将是非常烦人的。但是,如果真的没有其他方法,也将不胜感激任何有关继续进行的帮助。
最佳答案
StackOverflow 之外的人为我提供了解决问题的方法。
.so 文件不需要是实际的 ELF 文件。它也可以是链接描述文件。链接器脚本是包含链接器指令的文本文件。就我而言,脚本非常简单。我只是将此文本文件安装为 libmine.so
:
INPUT ( /install/prefix/lib/libmine.so.1 -lother )
这指示链接器在命令行中出现 libmine.so
(或 -lmine
)的位置查找我的库(带有版本后缀,所以它会选择实际的 ELF 文件),然后搜索 other
库的库路径。
然后我只需将 /install/prefix
替换为构建脚本中实际配置的安装前缀,我就可以开始了。
关于Linux 等效于 Windows DLL 转发器或 MacOS reexport_library,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22764734/