gcc link shared library against symbolic link
Asked Answered
P

1

11

I have two libraries, for example two toaster libraries libtoaster_a.so and libtoaster_b.so and all the associated major/minor/rev symlinks eg libtoaster_a.so.1.0.0 etc. Both libraries implement the same toaster interface, but simply do the processing differently. Hence when I build an application that uses the library it doesn't matter which is used (from the applications perspective they are the same).

Because I would like to decide which library to use after the application has been compiled and distributed I make a symbolic link libtoaster.so which points to libtoaster.so.1 which can then point to either libtoaster_a.so.1 and libtoaster_b.so.1. Hence the user/installer could simply change the libtoaster.so.1 link to choose the implementation to use.

For the build say I have libtoaster.so.1 linked to libtoaster_a.so.1 by default. when I compile my application eg: my_app by something like gcc -o my_app -ltoaster... it compiles and even runs with libtoaster_a.so.1 correctly. However if I run ldd on my_app I will see it is linked to libtoaster_a.so.1 rather than libtoaster.so.1 as desired, hence changing the libtoaster.so.1 link has no effect.

Is there a nicer way to fix this than making libtoaster_a.so.1, renaming it to libtoaster.so.1, making my_app against this library then deleting libtoaster.so.1 and creating it as a symbolic link again?

Pantalets answered 14/6, 2011 at 5:19 Comment(0)
C
8

When you build the shared libraries, add "-Wl,-soname=libtoaster.so.1" to the gcc flags (assuming you are linking with gcc). This sets DT_SONAME in the library, and will force any application linked against that library to have the name of the library taken from the DT_SONAME, rather than from the name of the file.

[vps@manticore]~/cprog/toaster1$ gcc -c my_app.c
[vps@manticore]~/cprog/toaster1$ gcc -c toaster.c
[vps@manticore]~/cprog/toaster1$ gcc -o libtoaster_a.so -shared -Wl,-soname=libtoaster.so toaster.o
[vps@manticore]~/cprog/toaster1$ gcc -R$(pwd) -L. -ltoaster_a -o my_app my_app.o
[vps@manticore]~/cprog/toaster1$ ldd my_app
my_app:
my_app: can't load library 'libtoaster.so'
my_app: exit status 4
[vps@manticore]~/cprog/toaster1$ ln -s libtoaster_a.so libtoaster.so
[vps@manticore]~/cprog/toaster1$ ldd my_app
my_app:
    Start    End      Type Open Ref GrpRef Name
    1c000000 3c004000 exe  1    0   0      my_app
    05b1f000 25b23000 rlib 0    1   0      /home/vps/cprog/toaster1/libtoaster.so
    084f9000 28532000 rlib 0    1   0      /usr/lib/libc.so.51.0
    09e80000 09e80000 rtld 0    1   0      /usr/libexec/ld.so
[vps@manticore]~/cprog/toaster1$
Creekmore answered 14/6, 2011 at 6:40 Comment(2)
But what if I'm not compiling the library? is there a way to do this from the other side? to tell the linker of the loading side not to follow symlinks?Hushhush
@Hushhush AFAIU, this is not about about reading symbolic links. All libraries have DT_SONAME, and when linking, linker is required to use that value. I don't see any linker options that overrides used DT_SONAME for a library that you are linking against.Creekmore

© 2022 - 2024 — McMap. All rights reserved.