动态库的创建
Linux 系统上经常见到的 *.so 文件其实就是动态库,将一个 *.c 文件编译成动态库很简单:
-fPIC
选项用来指导编译器生成位置无关代码(position-independent code),在Linux/x86-64系统上必须指定这个选项。
动态库规范
动态库的升级通常也分为小版本的升级和主版本的升级,通常来说主版本的升级是不兼容的,而小版本的升级则是兼容的。动态库通常有一种规范的命名方式,为的是能够清晰地了解不同版本之间的关系:
在编译动态库的时候,通常会为动态库创建一个 soname,作为动态库的别名,例如,这里我们给动态库libdemo.so.1.0.1
创建了一个 soname 叫做libdemo.1
:
在生产环境下,用户自己创建的动态库一般不能随便放置(防止找不到或者不小心被删除了),所以推荐放在系统目录/usr/local/lib/
下面:
通常来说,系统会在/etc/ld.so.cache
这个文件里面缓存系统的动态库列表。如果用户自己添加了动态库,那么还需要用ldconfig
命令去更新系统的动态库缓存列表,同时这个命令会自动创建一个与 soname 同名的符号链接,指向对应的动态库:
通过这些步骤就顺利安装好了动态库了。那么还有一个问题,在编译程序时,怎么让 linker 找到动态库的位置呢?最简单的方法可以这样做:
在链接的过程中,如果动态库拥有 soname,那么 linker 会将这个 soname 嵌入到可执行文件中,如果动态库没有 soname,嵌入的则是动态库的真名。我们可以用readelf
命令看到可执行文件main
的 header 中是否包含动态库的信息:
可以看到,可执行文件main
中只记录动态库的 soname。
上面的编译命令需要用户知道动态库的具体位置,然而用户在编译程序时,才不会想知道动态库的位置呢!解决这个问题很简单,我们可以创建一个符号链接,让它指向libdemo.so.1
就好了:
这样编译程序的时候就简单多了: