【问题标题】:Abusing soversion minor revision to support optional dependencies滥用 soversion 次要版本来支持可选依赖项
【发布时间】:2014-06-29 17:04:44
【问题描述】:

我正在编写一个带有许多可选依赖项的 C++ 包。重要的是能够在没有任何这些依赖项的情况下使用包,然后能够在不重新编译软件的情况下添加依赖项。如果依赖项不可用,我想回退到一些默认行为。

每个可选依赖项对应于包的不同共享库,我正在考虑(ab)使用“soversions”来实现此功能,并让次要修订版 0 对应于后备实现。

为了说明,假设有一个核心模块编译到名为“libmy_core.so”的共享库中。我有一个可选功能(取决于“libmy_core.so”以及一些外部包)编译到共享库“libmy_feature.so.1.1”中。但是为了确保代码在没有这个库的情况下也能正常工作,我还构建了一个名为“libmy_feature.so.1.0”的备用模块,它依赖于“libmy_core.so”。

然后我将分发“libmy_core.so”和“libmy_feature.so.1.0”。如果用户稍后添加可选的依赖项,“libmy_feature.so.1.1”也将被安装(并优先于“libmy_feature.so.1.0”)。

这是一个可行的解决方案还是有更好的解决方案?类似的方法是否也适用于非 Linux 系统,尤其是 OS X 和 Windows?

【问题讨论】:

    标签: c++ plugins shared-libraries versioning dependency-management


    【解决方案1】:

    这是一个可行的解决方案还是有更好的解决方案?

    这不是一个好的解决方案。您正在让自己和您的用户陷入依赖地狱。下面是一个可行的替代方案。和plugin库的思想有关。

    您可以在公开 C 接口的共享库中构建可选功能。然后,您的应用程序/库可以使用dlopen 检查共享库的存在,然后使用dlsym 获取接口。如果找不到共享库或未公开所需的接口,您的应用程序/库可以使用回退行为,该行为在应用程序/库本身中实现。您必须小心,您的应用程序/库不依赖于可选库,而是仅使用 dlsym 返回的函数指针。

    之所以使用 C 接口,是因为它提供了稳定的二进制接口。对于 C++ 类型,当混合使用不同编译器编译的共享库或使用不同的编译器设置时,您可能会得到未定义的行为。

    在 Windows 上,您可以使用 LoadLibraryGetProcAddress 执行相同操作。

    【讨论】:

    • 感谢您的评论,但我认为这并不能回答关于使用 soversion 的原始问题。
    • @Joel 我回答了您的问题“有更好的解决方案吗?”,但如果您愿意,我不介意补充说您最初的想法很糟糕。查看我的编辑。
    • 谢谢!你可能是对的,使用 soversion 不是要走的路。最好采用更传统的插件方法并在需要时进行修改。我已经给你赏金了。
    【解决方案2】:

    我会用dlopen 加载可选库。然后您只需要一个库,并且可以使用 dlopen 返回值在运行时检测另一个库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 2012-12-02
      • 2018-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多