views:

81

answers:

1

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.

+2  A: 

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.

bdonlan
Good answer! It answered the three important questions: "Can it be done in the preferred way?" (no), "How do others do?" (pkg-config) and "Can it be done in some hackish way?" (yes). I will go with the -ldl requirement in this case.
matli