我可以用静态版本替换共享库的依赖项吗?

时间:2014-04-14 16:36:14

标签: c++ shared-libraries static-libraries wrapper

我有一个依赖于C ++共享库libfoo.so的应用程序。我没有libfoo.so的源代码,只有描述其接口的头文件和共享库文件本身。 libfoo.so已链接到包含libbar.so.1作为依赖项。我的应用程序也使用libbar.so,但它使用ABI不兼容的修订版libbar.so.2

回顾一下,这里是依赖关系的粗略层次结构:

- myapp
    - libbar.so.2
    - libfoo.so
        - libbar.so.1

此设置会导致问题,因为我从两个libbar版本中获得了多重定义的符号。 libbar是一个开源库,我的静态库libbar.a.1可用。

是否可以在运行时不再依赖libfoo.so的方式修改或包装libbar.so.1?具体来说,我想过做这样的事情:

  • 创建一个包含libfoowrapper.so和静态库libfoo.so的包装器共享库libbar.a.1

  • 以某种方式隐藏libbar.a.1中的符号,以便它们不会从libfoowrapper.so导出。

  • 以某种方式消除libfoowrapper.so与其第二级依赖关系libbar.so.1之间的运行时依赖关系。

这可能吗?我目前在类Unix系统(Linux,MacOS)上使用gcc,而我将来可能不得不使用Visual Studio进行Windows操作。

1 个答案:

答案 0 :(得分:1)

  

是否可以修改或包装libfoo.so,使其在运行时不再依赖libbar.so.1?

否:大多数UNIX系统(AIX除外)都会考虑.so 最终链接产品。无法进一步修改。

您有几个选择:

  • 询问您的"供应商" libfoo.so的{​​{1}}为您提供取决于libbar.so.2的更新版本。这是最好的解决方案。
  • 不要直接依赖libfoo.so,而是使用dlopen("libfoo.so", RTLD_LAZY|RTLD_LOCAL);动态加载它。 RTLD_LOCAL部分将确保libfoo.so位于单独的链接程序命名空间中,而libbar.so.1中的符号不​​会被libfoo.so以外的任何内容使用。