滥用soversion minor revision来支持可选的依赖项

Abusing soversion minor revision to support optional dependencies

本文关键字:依赖 支持 soversion minor revision 滥用      更新时间:2023-10-16

我正在编写一个带有许多可选依赖项的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 "answers" libmy_feature.so.1.0 "。如果用户后来添加了可选的依赖," libmy_feature.so.1.1 "也将被安装(并且优先于"libmy_feature.so.1.0 ")。

这是可行的解决方案还是有更好的解决方案?类似的方法是否也适用于非linux系统,特别是OS X和Windows?

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

这不是一个好的解决方案。您正在为自己和用户设置依赖地狱。下面是一个可行的替代方案。这与插件库的思想有关。

可以在公开C接口的共享库中构建可选特性。然后,应用程序/库可以使用dlopen检查共享库的优先级,然后使用dlsym获取接口。如果没有找到共享库或没有公开所需的接口,应用程序/库可以使用回退行为,这是在应用程序/库本身中实现的。您必须注意,您的应用程序/库不依赖于可选库,而只使用dlsym返回的函数指针。

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

在Windows上,你可以使用LoadLibrary和GetProcAddress来做同样的事情。

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