27

I am trying to build a shared library. Let us say libabc.so. It uses another .so file , say lib123.so (a lib in /usr/local/lib). Now I am using my shared lib libabc.so in my application. Say my-app. I want to know how I should link these binaries? I don't want to link my-app with lib123.so directly. my-app should be linked with only libabc.so. How can I do this?

Thanks in advance. I am using g++ compiler.

Danijel
  • 8,198
  • 18
  • 69
  • 133
A R
  • 2,697
  • 3
  • 21
  • 38

3 Answers3

31

Suppose that libabc.so is obtained from posiition independent object code files abc1.pic.o and abc2.pic.o ; then you have built them with e.g.

 gcc -Wall -fPIC -O -g abc1.c -c -o abc1.pic.o
 gcc -Wall -fPIC -O -g abc2.c -c -o abc2.pic.o

and you build libabc.so with

gcc -shared  abc1.pic.o  abc2.pic.o -L/usr/local/lib -l123 -o libabc.so

I added -L/usr/local/lib before -l123 because I am assuming you have a /usr/local/lib/lib123.so shared library.

Read also the Program Library HowTo.

As you see, you may link a shared library lib123.so into your own shared library libabc.so

Then check with ldd libabc.so

You may want to set up some rpath in your libabc.so by adding -Wl,-rpath and -Wl,$RPATHDIR to the linking command.

For much more details, read Drepper's paper How to write shared libraries

PS. Don't use a static library for lib123.a (it should be PIC). If you link non-PIC code into a shared object, you lose most of the advantages of shared objects, and the dynamic linker ld.so has to do zillions of relocations.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 1
    I had done exactly the same thing you mentioned here. But when i do a ldd on libabc.so , it is not listing lib123.so. Do you know why it is like that? – A R Oct 17 '13 at 10:56
  • Why not a static library for lib123? What if it is not PIC? – BЈовић Oct 17 '13 at 11:05
  • 1
    I cannot help, unless you **show** at least the **precise commands** involved in building your `abc*.pic.o` objects and the `libabc.so` library. – Basile Starynkevitch Oct 17 '13 at 11:05
  • @BЈовић: Because static libraries are non-PIC in general, and are basically a catenation of member object files. – Basile Starynkevitch Oct 17 '13 at 11:06
  • Please edit your question. And tell there *exactly* how you build both `abc.pic.o` and `libabc.so` – Basile Starynkevitch Oct 17 '13 at 11:26
  • g++ -Wall -fPIC -O -g abc.cpp -c -o abc.pic.o g++ -shared abc.pic.o -L. -l123 -o libabc.so Is it right? When i do a ldd on libabc.so i didnt see lib123.so – A R Oct 17 '13 at 11:29
  • 1
    Please, please **edit your question**. Your comments above are nearly unreadable! – Basile Starynkevitch Oct 17 '13 at 11:33
  • sorry i am not able to edit that comment. i cant find lib123.so while i do an ldd on libabc.so – A R Oct 17 '13 at 11:48
  • You probably should be able to edit your own initial [question](http://stackoverflow.com/q/19424494/841108) (not the comments). – Basile Starynkevitch Oct 17 '13 at 11:49
  • g++ -Wall -fPIC -O -g abc.cpp -c -o abc.pic.o – A R Oct 17 '13 at 11:49
  • g++ -shared abc.pic.o -L. -l123 -o libabc.so – A R Oct 17 '13 at 11:50
  • I don't understand why you put `-L.`; you probably want `-L/usr/local/lib` instead. – Basile Starynkevitch Oct 17 '13 at 11:51
  • i made a lib123.so just to test. it is in current folder – A R Oct 17 '13 at 11:53
  • If linking with non -fPIC compiled files work then the loader will have to do a lot of relocations BUT once once and not on each function call or global variable use. This can speed up the executable quite a lot 10% in average to 20% in special cases. Because it reduces lots of cache misses caused by indirection. – Lothar May 13 '17 at 01:48
  • I almost lost hope, but then I saw comment from @luighi-anthony-vitón-zorrilla `in some versions of gcc the order where library references are placed, is important` So keeping -l end of gcc command solved the issue of linking and thats already a real bad feeling working with gcc verion 8.4.0.. Why should order of param change behavior of outcome.. – ashish Nov 20 '20 at 16:45
  • Hello Basile, I have a similar issue and using `-fPIC` does not fix it, could you have a look at this question I posted: https://stackoverflow.com/questions/65603457/c-linux-lib1-use-lib2-main-uses-lib1-why-shall-it-be-linked-to-lib2? – jpo38 Jan 06 '21 at 21:19
2

When trying to create my own shared library that uses Berkeley DB, I found that I have to put the -ldb at the end of the gcc command or else it blew up saying the symbol 'db_create' was not found. This was under Cygwin.

Specifically, this worked:

gcc -shared -o $b/$libfile nt_*.o -ldb

This did not work:

gcc -ldb -shared -o $b/$libfile nt_*.o

2

Following the same procedure pointed out by Basile Starynkevitch, for example, I have a library which depends on libm.so, so the compilation for the library objects are:

gcc -fPIC -Wall -g -I include -I src -c src/wavegen.c  -o build/arm/wavegen.o                                                                                          
gcc -fPIC -Wall -g -I include -I src -c src/serial.c  -o build/arm/serial.o

To compile the library, however, in some versions of gcc the order where library references are placed, is important, so I suggest, to ensure compatibility, placing those references at the end of the command:

gcc -shared -Wl,-soname,libserial.so.1 -o lib/libserial.so.1.0 build/arm/wavegen.o build/arm/serial.o -lm

I have tested in PC (gcc v.8.3.0) and in ARM (gcc v.4.6.3).