-1

I’m creating a library that depends on other libraries (libpng, libX11, etc.). I would like to know if it is possible (with some flags, for example) for the user binary not to directly link to the third party libraries but rather indirectly via my lib.

Here is an example:

libb.c (as the third party lib)

int get21()
{ return 21; }

liba.c (as my lib)

int get21();
int get42()
{ return get21() * 2; }

main.c (as the user code)

int get21();
int get42();
int main()
{
  printf("42 = %d\n21 = %d\n", get42(), get21());
  return 0;
}

Compilation

$ gcc -fPIC -shared libb.c -o libb.so
$ gcc -fPIC -shared liba.c -L. -lb -Wl,-rpath=. -o liba.so
$ gcc main.c -L. -la -Wl,-rpath=.
/usr/bin/ld: /tmp/ccVm8exQ.o: undefined reference to symbol 'get21'
./libb.so: error adding symbols: DSO missing from command line

Normally, I would need to link the main with -lb too. But I don’t want to final user to have to link against all libraries, as it is cumbersome and might change in the future. Is there a possibility of avoiding that?

lesenk
  • 761
  • 1
  • 8
  • 21
  • Possible duplicate of [How to combine several C/C++ libraries into one?](http://stackoverflow.com/questions/13128/how-to-combine-several-c-c-libraries-into-one) – πάντα ῥεῖ Jan 26 '15 at 19:29
  • @πάνταῥεῖ No, that question is about static linking, my question is about dynamic linking. – lesenk Jan 26 '15 at 19:30
  • You can combine the `.a` stubs for dynamically linked libraries into an `ar` archive though. Did you try this already? – πάντα ῥεῖ Jan 26 '15 at 19:33
  • @πάνταῥεῖ I don't really understand, should I provide the `.a` files? That's not to me to provide the lib's dependencies, that is the whole point of dynamic linking. I also don't know the version of these libs on the user system. – lesenk Jan 26 '15 at 19:38
  • Is your example actually representative of your case? I could understand if you want to avoid the user having to link libraries that are needed only because yours calls functions from them. In the example, however, the program's `main()` is calling functions from both libraries directly. In that case, both libraries definitely need to be included in the link. – John Bollinger Jan 26 '15 at 19:40
  • @JohnBollinger Yes, the user code may call directly the third party libraries. Therefore, I suppose it is the responsibility of the user to link with the appropriate libs. – lesenk Jan 26 '15 at 19:53
  • @KévinLesénéchal You can use the `ar` tool to combine several `.a` library files into a combined library file. Whenever you have `.so` files, you are actually linking to `.a` stub files corresponding to them. – πάντα ῥεῖ Jan 26 '15 at 19:55
  • @πάνταῥεῖ, perhaps some toolsets on some systems work that way, but not the gcc (per the tag) and the rest of the GNU toolset. With gcc, linking an executable against shared libraries does not require any `.a` files to be present anywhere on the system, neither at build time nor at run time. You link directly against the shared library file. – John Bollinger Jan 26 '15 at 20:08
  • In similar vein, suppose that there is a library `libb`, some of whose functions were called by another library `liba`, and that there is a main program that calls functions from `liba` but not (directly) any functions from `libb`. In that case it is a function of the toolset whether the main program needs to be linked against both `liba`and `libb`, or only against `liba`. To the best of my knowledge, the GNU toolset provides no way to avoid linking both libraries. – John Bollinger Jan 26 '15 at 20:13
  • @KévinLesénéchal, yes, it is the user's responsibility to link libraries with which to resolve all the external symbols referenced by his own code. – John Bollinger Jan 26 '15 at 20:16
  • possible duplicate of [Linking with dynamic library with dependencies](http://stackoverflow.com/questions/11055569/linking-with-dynamic-library-with-dependencies) – dewaffled Jan 26 '15 at 20:23
  • Some fancy ideas: 1) look for "filter" in the documentation of `ld`, or 2) look at the content of the file `libc.so` (**not** `libc.so.6`) on a random linux box. – Marc Glisse Jan 27 '15 at 06:59

1 Answers1

0

I think you are asking about dynamic libraries, not static ones (as per the majority of the comments).

If so, yes, this is possible.

Suppose you have a dynamic library (.so) called A, which in turn uses other dynamic link libraries B and C. A binary X which wishes to use library A only needs to link to library A, and libraries B and C will be automatically pulled in. Note that X would need to link explicitly to B or C (and include their header files) for X to use anything in B or C directly (as opposed to via A).

Here's a live example. As you can see xml2-config says the right way to link to libxml2 is merely to use -lxml2. However, ldd shows that it in turn is linked to various other libraries, including liblzma (for instance). A program using libxml2 does not need to specify -llzma on the link line unless it uses liblzma directly.

$ xml2-config --libs
-lxml2
$ ldd /usr/lib/x86_64-linux-gnu/libxml2.so
    linux-vdso.so.1 =>  (0x00007fff157c9000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f7c51805000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f7c515ec000)
    liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f7c513c9000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f7c510c3000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7c50cfd000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f7c51d93000)

If you are asking how to do this, the key thing I've found is to persuade ldd that the libraries it uses are properly linked in. I tend to libtool for that.

abligh
  • 23,144
  • 3
  • 41
  • 81