GCC/G++选项 -Wl,--soname,xxx

    在类Unix系统中,一个动态库在其数据段提供了一个 SONAME 字段,用于指定该动态库的实际链接名称。该字段在编译动态库时通过-Wl,--soname,xxx 选项指定,其中xxx就是实际链接名称,该实际链接名称往往同动态库文件名不同。默认情况下(没有指定 --soname选项),动态库的链接名称就是动态库的文件名。

    示例代码如下:

    test.cc:

#include <iostream>

void dumpTest() {
    std::cout << "This is dumpTest" << std::endl;
}
    main.cc:

#include <iostream>

extern void dumpTest();
int main() {
    std::cout << "This is Linux platform" << std::endl;
    dumpTest();

    return 0;
}
说明:test.cc编译成动态库 libtest.so,main.cc编译链接libtest.so并最终生成可执行文件 main。

    问题:考虑如下应用场景,开发者通过so提供服务,定期更新so版本,并在更新过程中有可能出现问题需要回退版本。还有可能提供其他不在主线分支的特定功能版本。这种情况下,通过传统的搜索文件名加载动态库的方式比较麻烦,需要频繁修改so文件名,或者修改编译可执行文件的链接选项,极有可能出错。

    解决办法:通过 -Wl,--soname,xxx 选项指定实际的链接名称,-o 选项指定so名称来解决。这种情况下,不同功能/版本的so文件名不同,但是实际的链接名称都相同,只要创建一个链接名称的软连接,指向不同功能/版本的so,即可方便的切换so。

    (1)生成多版本的so,文件名不同,链接名称相同(libtest.so):

            $ g++ -fPIC -shared -Wl,--soname,libtest.so -o libtest.1.so test.cc

            $ g++ -fPIC -shared -Wl,--soname,libtest.so -o libtest.2.so test.cc

            $ g++ -fPIC -shared -Wl,--soname,libtest.so -o libtest.3.so test.cc

            查看SONAME:

$ readelf -d libtest.3.so 

Dynamic section at offset 0xde0 contains 26 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [libtest.so]
 0x000000000000000c (INIT)               0x7d0
 0x000000000000000d (FINI)               0x9d0
 0x0000000000000019 (INIT_ARRAY)         0x200dc0
 0x000000000000001b (INIT_ARRAYSZ)       16 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x200dd0
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x1f0
 0x0000000000000005 (STRTAB)             0x410
 0x0000000000000006 (SYMTAB)             0x230
 0x000000000000000a (STRSZ)              417 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (PLTGOT)             0x201000
 0x0000000000000002 (PLTRELSZ)           144 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x740
 0x0000000000000007 (RELA)               0x620
 0x0000000000000008 (RELASZ)             288 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x5e0
 0x000000006fffffff (VERNEEDNUM)         2
 0x000000006ffffff0 (VERSYM)             0x5b2
 0x000000006ffffff9 (RELACOUNT)          4
 0x0000000000000000 (NULL)               0x0
 

    (2)生成so的链接文件libtest.so

            $ ldconfig -nv .
                .:
                    libtest.so -> libtest.3.so (changed)

                该命令搜索当前目录下的所有so,创建链接库,并更新链接库cache。

                    $ ls -al
                        -rwxrwxr-x 1 colin colin 8612 Oct  8 11:38 libtest.1.so
                        -rwxrwxr-x 1 colin colin 8612 Oct  8 11:38 libtest.2.so
                        -rwxrwxr-x 1 colin colin 8612 Oct  8 11:38 libtest.3.so
                        lrwxrwxrwx 1 colin colin   12 Oct  8 11:41 libtest.so -> libtest.3.so
                        -rwxrwxr-x 1 colin colin 9179 Oct  8 11:44 main

    (3)编译生成可执行文件main

            $ g++ -L. -o main main.cc -ltest

    (4)如果需要更改so,main不需要变动,只需要重新连接libtest.so即可:

            $ ls -al
                total 64
                -rwxrwxr-x 1 colin colin 8612 Oct  8 11:38 libtest.1.so
                -rwxrwxr-x 1 colin colin 8612 Oct  8 11:38 libtest.2.so
                -rwxrwxr-x 1 colin colin 8612 Oct  8 11:38 libtest.3.so
                lrwxrwxrwx 1 colin colin   12 Oct  8 12:29 libtest.so -> libtest.1.so
                -rwxrwxr-x 1 colin colin 9179 Oct  8 11:44 main

转载于:https://my.oschina.net/yepanl/blog/2231318

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值