【问题标题】:Static library depending on shared library依赖于共享库的静态库
【发布时间】:2010-08-30 12:05:22
【问题描述】:

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

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

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

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

编辑:我知道 libtool 可能会解决这个问题,但这仍然会进一步改变所有应用程序的构建过程,我希望避免这种情况。

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

【问题讨论】:

  • 什么操作系统?除非您更具体,否则很难回答...
  • 对不起,忘了提到操作系统。编辑添加。

标签: c shared-libraries unix


【解决方案1】:

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

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

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

当你链接时:

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

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

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

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

【讨论】:

  • 好答案!它回答了三个重要问题:“可以以首选方式完成吗?” (不),“别人怎么做?” (pkg-config)和“可以以某种骇人听闻的方式完成吗?” (是的)。在这种情况下,我将使用 -ldl 要求。
猜你喜欢
  • 2021-11-21
  • 1970-01-01
  • 2021-06-04
  • 1970-01-01
  • 1970-01-01
  • 2011-10-01
  • 2012-06-19
  • 2012-06-21
相关资源
最近更新 更多