静态库依赖于共享库

发布于 2024-09-16 09:00:38 字数 456 浏览 2 评论 0原文

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

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

是否可以以某种方式创建一个静态库,它将自动(在编译时或运行时)引入所需的共享库?

让静态库依赖于共享库是否被认为是好的做法?

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

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

I have created a communication library which is linked statically into several different applications. The library provides support for communication via different kinds of hardware. Some of the hardware is supported from the vendor via a shared library. On systems without those kinds of hardware, the shared library is not available.

Previously we handled this by compiling dual versions of the communication library and the applications. This is however not very practical, so I thought about using a more dynamic communication library which tries to load the vendor library with dlopen()/dlsym() if it is available. This seems to work well. But a problem is that everyone who use my library will need to pass the -ldl option when linking their application with my library. Even if this is a minor nuisance I wonder on how this is normally solved.

Is it somehow possible to create a static library that will automatically (at compile-time or run-time) bring in the needed shared library?

Is it considered good practice to let static libraries have dependencies on shared libraries?

EDIT: I know that libtool could probably solve this, but that would still change the build process for all applications even more, which I would prefer to avoid.

EDIT 2: Target platforms are primarily Linux and Solaris. Gcc as compiler.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

兲鉂ぱ嘚淚 2024-09-23 09:00:38

我不了解 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 之间的接口是私有且不稳定的——它可能在任何 glibc 版本中发生变化,包括次要版本和错误修复版本。仅当您控制所部署的 glibc 版本并准备在必要时重建应用程序时才执行此操作。另请注意,如果您的库本身不是 LGPL,那么使用这样的私有 API 可能会出现许可问题;不知道 LGPL 的情况如何。

I don't know about Solaris, so assume everything in my answer here applies to Linux only (although pkg-config should be usable on Solaris too).

First off, there's no supported way for a static library to pull in a link-time dependency. Sorry. Most libraries use something like pkg-config for this - that is, when you build, you add to the compiler command line:

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

and when you link:

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

Note that the --libs parameter, in this case, would produce something like -ldl -lyourlib as output. The --cflags parameter may produce no output, or it may add some include paths.

If you absolutely need it to work with just a -lyourlib, though, and you don't mind being tied to a unsupported and unstable interface in glibc... Well, libdl is just a thin wrapper over some routines in the dynamic linker, via an undocumented vtable. If you look at the source under the dlfcn/ directory of the version of glibc in use, you should be able to replicate what it does.

HOWEVER, the interface between libdl and ld-linux is PRIVATE and UNSTABLE - it may change at any glibc release, including minor and bugfix releases. ONLY do this if you control the version of glibc deployed, and are prepared to rebuild your application when necessary. Also note that if your library is not LGPL itself, then using a private API like this may have licensing issues; not sure how things stand with this for the LGPL.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文