静态库与共享库

来源:互联网 发布:气象数据同化PDF 编辑:程序博客网 时间:2024/04/29 06:12

静态库与共享库

  • “程序库”包含了数据和可执行代码的文件,其不能单独执行,可以作为其它执行程序的一部分来完成某些功能。库的存在,可以使得程序模块化,可以加快程序的再编译,可以实现代码重用,可以使得程序便于升级,同时也保证了代码的保密性。程序库可分静态库(static library)和共享库(shared object)。
  • 静态库是在可执行程序运行前就已经加入到执行码中,成为执行程序的一部分。共享库,是在执行程序启动时加载到执行程序中,可以被多个执行程序共享使用。
  • 静态库在应用程序生成时,可以不必再编译,节省再编译时间。但在编译器越来越快的今天,这一点似乎已不重要。如果其他开发人员要使用你的程序,而你又不想给其源码,提供静态库是一种选择。从理论上讲,应用程序使用了静态库,要比使用动态加载库速度快1-5%,但实际上可能并非如此。由此看来,除了使用方便外,静态库可能并非一种好的选择。
  • 共享库比较明显的优势在于库是独立的,便于维护和更新;同时共享库节约程序的内存,可以避免相同代码 加载到程序中是的程序过大。

这里写图片描述

静态库

静态库可以认为是一些目标代码的集合。按照习惯,一般以“.a”做为文件后缀名。使

用ar(archiver)命令可以创建静态库。

  • 首先把要加入静态库的文件生成.o文件

    gcc -c add.c sub.c mul.c dive.c

  • 再通过ar rcs命令生成静态库,静态库以lib开头命名

ar rcs libmycalc.a add.o sub.o mul.o dive.o


  • 静态库创建成功后,需要链接到应用程序中使用。使用gcc的-l选项来指定静态库,使用-L参数来指定库文件的搜索路径。比如上述例子应指定-lmylib,所有库文件名都以lib开头,开头的lib在指定参数时应省略。-l和-L之后都直接带参数而不跟空格。

gcc -Iinclude/ test.c -lmycalc -Llib/ -o app

动态库

  • 首先使用-fPIC或-fpic生成与代码无关的.o文件。

    gcc -c -fPIC add.c sub.c mul.c dive.c

  • 再使用.o文件生成共享库

    gcc -shared -Wl,soname,libmycalc.so.1 -o libmycalc.so.1.0.1 add.o sub.o mul.o dive.o

  • 在启动一个ELF二进制执行程序时,一个特殊的程序“程序装载器”会被自动装载并运行。在linux中,这个程序装载器就是/lib/ld-linux.so.X(X是版本号)。它会查找并装载应用程序所依赖的所有共享库。被搜索的目录保存在/etc/ld.so.conf文件中。

sudo vim /etc/ld.so.conf
加上共享库的路径

  • 更新查找共享库的路径

    sudo ldconfig -v

  • 手动添加link nam

    ln -s libmycal.so.1.0.1 libmycal.so

  • 按照共享库的命名惯例,每个共享库有三个文件名:real name、soname和linker name。真正的库文件(而不是符号链接)的名字是real name,包含完整的共享库版本号。soname是一个符号链接的名字,只包含共享库的主版本号,主版本号一致即可保证库函数的接口一致,因此应用程序的.dynamic段只记录共享库soname,只要soname一致,这个共享库就可以用。如libmyab.so.1和libmyab.so.2是两个主版本号不同的libmyab,有些应用程序依赖于libmyab.so.1,有些应用程序依赖于libmyab.so.2,但对于依赖libmyab.so.1的应用程序来说,真正的库文件不管libmyab.so.1.10还是libmyab.so.1.11都可以用,所以使用共享库可以很方便地升级库文件而不需要重新编译应用程序,这是静态库所没有的优点。注意libc的版本编号有一点特殊,libc-2.8.90.so的主版本号是6而不是2或2.8。linker name仅在编译链接时使用,gcc的-L选项应该指定linker name所在的目录。有的linker name是库文件的一个符号链接,有的linker name是一段链接脚本。例如上面的libc.so就是一个linker name,它是一段链接脚本

1 0
原创粉丝点击