我创建了一个静态链接到几个不同应用程序的通信库。该库通过不同类型的硬件为通信提供支持。供应商通过共享库支持某些硬件。在没有这些类型硬件的系统上,共享库不可用。

以前我们通过编译通信库和应用程序的双版本来处理这个问题。然而,这不是很实用,所以我考虑使用一个更动态的通信库,如果它可用,它会尝试使用 dlopen()/dlsym() 加载供应商库。这似乎运作良好。但问题是,使用我的库的每个人在将他们的应用程序与我的库链接时都需要传递 -ldl 选项。即使这是一个小麻烦,我想知道这通常是如何解决的。

是否有可能创建一个静态库来自动(在编译时或运行时)引入所需的共享库?

让静态库依赖于共享库是否被认为是一种好习惯?

编辑:我知道 libtool 可能会解决这个问题,但这仍然会更多地改变所有应用程序的构建过程,我宁愿避免这种情况。

编辑 2:目标平台主要是 Linux 和 Solaris。 gcc 作为编译器。

最佳答案

我不了解 Solaris,因此假设我在这里的答案中的所有内容仅适用于 Linux(尽管 pkg-config 也应该可用于 Solaris)。

首先,静态库不支持引入链接时依赖项的方式。对不起。大多数库为此使用类似 pkg-config 的东西 - 也就是说,当你构建时,你添加到编译器命令行:

gcc `pkg-config --cflags your-library` [...]

当您链接时:
gcc `pkg-config --libs your-library` [...]

请注意,在这种情况下,--libs 参数会产生类似 -ldl -lyourlib 的内容作为输出。 --cflags 参数可能不会产生任何输出,或者它可能会添加一些包含路径。

但是,如果您绝对需要它只使用 -lyourlib ,并且您不介意被绑定(bind)到 glibc 中不受支持且不稳定的接口(interface)......好吧,libdl 只是动态链接器中某些例程的薄包装,通过一个未记录的 vtable。如果您查看正在使用的 glibc 版本的 dlfcn/ 目录下的源代码,您应该能够复制它的功能。

然而,libdl 和 ld-linux 之间的接口(interface)是私有(private)且不稳定的——它可能会在任何 glibc 版本中发生变化,包括次要版本和错误修复版本。仅当您控制部署的 glibc 版本并准备在必要时重建您的应用程序时才执行此操作。另请注意,如果您的库本身不是 LGPL,那么使用像这样的私有(private) API 可能存在许可问题;不确定 LGPL 的情况如何。

关于c - 静态库依赖于共享库,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3600121/

10-13 08:31