【GCC】参数选项笔记

编程入门 行业动态 更新时间:2024-10-10 06:15:30

【GCC】参数<a href=https://www.elefans.com/category/jswz/34/1771211.html style=选项笔记"/>

【GCC】参数选项笔记

-Wl,-soname

(原文:)

-Wl选项告诉编译器将后面的参数传递给链接器。

-soname则指定了动态库的soname(短名,Short for shared object name)

-Wl 表示后面的参数也就是-soname,libhello.so.1直接传给连接器ld进行处理。每一个库都有一个soname,当连接器发现程序库(如:libhello_v1.so)中有soname (libhello.so),连接器便会将soname (libhello.so)嵌入要连接的二进制文件内,而不是库文件的实际文件名(libhello_v1.so)。在程序执行期间,程序会查找拥有 soname名字(libhello.so)的文件,而不是库的文件名,换句话说,soname是库的区分标志。

这样做的目的主要是允许系统中多个版本的库文件共存(soname相同,库文件名不同,可以放在同一个文件夹),习惯上在命名库文件的时候通常与soname相同

libxxxx.so.major.minor

其中,xxxx是库的名字,major是主版本号,minor 是次版本号

简单的来说,真正指定了库的名字的是soname (libhello.so)而不是库文件名libhello_v1.so)。在做连接是将这个soname指定的名字加入执行文件中,而程序运行是也是去加载soname指定的库文件名。

所以如果程序连接了新升级的库(libhello_v2.so),只需要将这个新库拷贝到目录下面后,对其以soname做一个符号链接就能调用(libhello.so-->libhello_v2.so)。如果库升级了,但是程序依旧使用旧的链接库,那么只需对这个将旧库名字软链接到新升级的库中去即可。

soname的关键功能是它提供了兼容性的标准:

当要升级系统中的一个库时,并且新库的soname和老库的soname一样,用旧库的链接指向新库依然能正常运行。这个特性使得在Linux下,升级使得共享库的程序和定位错误变得十分容易。

在Linux中,应用程序通过使用soname,来指定所希望库的版本,库作者可以通过保留或改变soname来声明,哪些版本是兼容的,这使得程序员摆脱了共享库版本冲突问题的困扰。

可以通过readelf -d来查看每个动态库的SONAME

1. 生成文件名为libto.so.1.2,但soname为 libto.so.1的库

[root@localhost c]# gcc -fPIC -shared -Wl,-soname,libto.so.1 -o libto.so.1.2 to.c
[root@localhost c]# ls -lh
-rwxr-xr-x 1 root root 4268 Jan 10 17:22 libto.so.1.2
[root@localhost c]# ldconfig -n ./
lrwxrwxrwx 1 root root   12 Jan 10 17:23 libto.so.1 -> libto.so.1.2
-rwxr-xr-x 1 root root 4.2K Jan 10 17:22 libto.so.1.2
[root@localhost c]# readelf -d libto.so.1.2Dynamic section at offset 0x504 contains 21 entries:Tag        Type                         Name/Value0x00000001 (NEEDED)                     Shared library: [libc.so.6]0x0000000e (SONAME)                     Library soname: [libto.so.1]0x0000000c (INIT)                       0x2cc0x0000000d (FINI)                       0x4c40x6ffffef5 (GNU_HASH)                   0xb40x00000005 (STRTAB)                     0x1b40x00000006 (SYMTAB)                     0xf40x0000000a (STRSZ)                      150 (bytes)0x0000000b (SYMENT)                     16 (bytes)0x00000003 (PLTGOT)                     0x15d80x00000002 (PLTRELSZ)                   24 (bytes)0x00000014 (PLTREL)                     REL0x00000017 (JMPREL)                     0x2b40x00000011 (REL)                        0x2940x00000012 (RELSZ)                      32 (bytes)0x00000013 (RELENT)                     8 (bytes)0x6ffffffe (VERNEED)                    0x2640x6fffffff (VERNEEDNUM)                 10x6ffffff0 (VERSYM)                     0x24a0x6ffffffa (RELCOUNT)                   10x00000000 (NULL)                       0x0


总结:程式库主要的升级会破坏相容性;而次要的升级则可能不会;那麽以下面的方式来连结,所有的一切就都会相安无事了。 
gcc -shared -Wl,-soname,libfoo.so.major -o libfoo.so.major.minor

连接库

静态库

-L/your/library/path  -l:libmylib.a

如果-l:filename格式指定一个文件名,连接程序直接去找这个文件名了,不会再像使用-lname时将name扩展成lib<name>.a格式的文件名.

当然如果库的位置不在gcc默认搜索路径中,要用-L参数另外指定搜索库的路径

更多推荐

【GCC】参数选项笔记

本文发布于:2024-03-11 23:04:03,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1730134.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:选项   参数   笔记   GCC

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!