gcc链接共享库符号链接 [英] gcc link shared library against symbolic link

查看:168
本文介绍了gcc链接共享库符号链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个库,例如两个toaster库 libtoaster_a.so libtoaster_b.so 以及所有关联的major / minor / rev符号链接,例如 libtoaster_a。 so.1.0.0 等。这两个库实现相同的烤面包机接口,但只是做不同的处理。因此,当我构建一个使用库的应用程序时,使用哪个应用程序并不重要(从应用程序的角度来看,它们是相同的)。

因为我想决定在编译和分发应用程序后使用的库我制作一个符号链接 libtoaster.so ,它指向 libtoaster.so.1 ,然后可以指向 libtoaster_a.so.1 libtoaster_b.so.1 。因此,用户/安装程序可以简单地更改 libtoaster.so.1 链接以选择要使用的实现。



libtoaster.so.1 默认链接到 libtoaster_a.so.1 。当我通过类似于 gcc -o my_app -ltoaster ... 编译我的应用程序时,例如: my_app ,它会编译甚至运行 libtoaster_a .so.1 正确。但是,如果我在my_app上运行ldd,则会根据需要将它链接到 libtoaster_a.so.1 ,而不是 libtoaster.so.1 ,因此将 libtoaster .so.1 链接无效。



有没有更好的方法可以解决这个问题,而不是制作 libtoaster_a.so.1 ,将它重命名为 libtoaster.so.1 ,使my_app针对这个库,然后删除 libtoaster.so.1 并将其重新创建为符号链接? 解决方案

在构建共享库时,将-Wl,-soname = libtoaster.so.1添加到gcc标志(假设您正在使用gcc进行链接)。这会在库中设置DT_SONAME,并强制任何与该库链接的应用程序拥有从DT_SONAME获取的库的​​名称,而不是来自文件的名称。

  [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:无法加载库'libtoaster.so'
my_app:退出状态4
[vps @ manticore]〜/ cprog / toaster1 $ ln -s libtoaster_a.so libtoaster.so
[vps @ manticore]〜/ cprog / toaster1 $ ldd my_app
my_app:
开始结束类型打开Ref GrpRef名称
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 $


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?

解决方案

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$

这篇关于gcc链接共享库符号链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆