Linux 库类型

Linux下可以创建两种类型的库:

静态库(.a): 在链接期间被应用程序直接链接进可执行文件

动态链接库(.so): 动态库还分为两种用法: a) 应用程序运行期间链接动态库,但是在编译期间声明动态库的存在,也就是说这种动态库必须在编译时对编译器可见,但编译器却不将此种库编译进可执行文件; b) 在运行期间,动态加载和卸载的库,使用动态加载方法加载。这种库的形式跟动态链接没有本质区别,区别是在调用时,是由用户程序决定何时链接的,而不是由系统链接器自动链接

命名约定

库需要以lib作为开头,而在指定链接命令行参数时,却无需包含开头和扩展名,例如:

gcc src-file.c -lm -lpthread

这个例子中,链接了libmath.a和libpthread.a

静态库(.a)

生成静态库的方法如下:

.a文件与windows下的.lib是相同的概念。

动态库(.so)

生成动态库的方法如下:

gcc -Wall -fPIC -c *.c

这个选项的目的是让编译器生成地址无关(position independent)的代码,这是因为,动态库是在运行期间链接的,变量和函数的偏移量是事先不知道的,需要链接以后根据offset进行地址重定向。

gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o

-shared选项是让动态库得以在运行期间被动态链接;-Wl,options是设置传递给ld(链接器)的参数,在上面的例子中,当链接器在链接.o时会执行ld -soname ibctest.so.1

上面的命令将最终输出一个动态库libctest.so.1.0,而出于习惯,会创建两个软链:

mv libctest.so.1.0 /opt/lib
ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so.1ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so

libctest.so用于在编译期间使用-lctest让编译器找到动态库,而libctest.so.1用于在运行期间链接

gcc -Wall -I/path/to/include-files -L/path/to/libraries prog.c -lctest -o prog

查看依赖

使用ldd命令来查看程序对动态库的依赖。例如:

ldd prog
libctest.so.1 => /opt/lib/libctest.so.1 (0x00002aaaaaaac000)
libc.so.6 => /lib64/tls/libc.so.6 (0x0000003aa4e00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003aa4c00000)

obj 文件

obj文件的格式和组成可能是系统差异性的一大体现,比如windows下的PE、linux和一些unix下的elf、macos的mach-o、aix下的xcoff。

查看obj文件的符号表信息,可以通过nm objdump readelf等方法。

运行期间查找动态库

运行期间,系统需要知道到哪里去查找动态库,这是通过/etc/ld.so.conf配置的。ldconfig用于配置运行时动态库查找路径,实际是更新/etc/ld.so.cache。另外一些环境变量也可以影响查找:(Linux/Solaris: LD_LIBRARY_PATH, SGI: LD_LIBRARYN32_PATH, AIX: LIBPATH, Mac OS X: DYLD_LIBRARY_PATH, HP-UX: SHLIB_PATH)

动态加载和卸载的库

需要应用程序希望设计成插件化的架构,这就需要可以动态加载和卸载库的机制。与动态链接不同的是,动态加载的意思是,编译期间可以对动态库的存在一无所知,而是在运行期间通过用户程序尝试加载进来的。

通过dlfcn.h中的dlopen、dlsym和dlclose等函数实现此种功能。

另外,使用到dlfcn机制的可执行文件需要使用-rdynamic选项,它将指示连接器把所有符号(而不仅仅只是程序已使用到的外部符号,但不包括静态符号,比如被 static 修饰的函数)都添加到动态符号表(即 .dynsym 表)里。

GNU Libtool

如今许多软件的编译都采用libtool工具,libtool是一个编译链接包装工具,实际只是一个脚本,用 libtool 编译和链接会产生类似.la的文件,.la这种文件其实是个文本文件,指向.a文件,并声明一些版本信息。

限时特惠:本站每日持续更新海量各大内部网赚创业教程,会员可以下载全站资源点击查看详情
站长微信:11082411

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。