【问题标题】:gcc link shared library against symbolic linkgcc 链接共享库反对符号链接
【发布时间】:2011-06-14 05:19:08
【问题描述】:

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

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

对于构建,我默认将 libtoaster.so.1 链接到 libtoaster_a.so.1。当我编译我的应用程序时,例如: my_app 通过类似gcc -o my_app -ltoaster... 它编译甚至运行 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 并再次将其创建为符号链接?

【问题讨论】:

    标签: gcc symlink ldd


    【解决方案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: 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$
    

    【讨论】:

    • 但是如果我不编译库怎么办?有没有办法从另一边做到这一点?告诉加载方的链接器不要遵循符号链接?
    • @shoosh AFAIU,这与阅读符号链接无关。所有库都有DT_SONAME,并且在链接时,链接器需要使用该值。对于您要链接的库,我没有看到任何覆盖使用 DT_SONAME 的链接器选项。
    猜你喜欢
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    • 2011-06-08
    • 2014-02-09
    • 2022-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多