2010-08-30 144 views
4

我已经创建了一个静态链接到几个不同应用程序的通信库。该库为通过不同种类的硬件进行通信提供支持。某些硬件通过共享库从供应商处获得支持。在没有这些硬件的系统上,共享库不可用。取决于共享库的静态库

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

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

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

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

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

+0

什么是操作系统?这很难回答,除非你更具体... – bdonlan 2010-08-30 12:30:31

+0

对不起,忘了提及操作系统。编辑添加。 – matli 2010-08-30 12:43:07

回答

4

我不了解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版本中发生更改,包括次要版本和bug修复版本。只有在您控制部署的glibc版本时才执行此操作,并准备在必要时重新构建应用程序。还要注意,如果你的库不是LGPL本身,那么使用这样的私有API可能会有许可问题;不知道LGPL的情况如何。

+0

很好的答案!它回答了三个重要问题:“它能以优先方式完成吗?” (不),“别人怎么做?” (pkg-config)和“可以用一些黑客的方式完成吗?” (是)。在这种情况下,我将遵循-ldl要求。 – matli 2010-08-30 14:05:10