Table of Contents
Using (Linking to) a Static Library
Displaying the Contents of a Library
Introduction
这篇文章告诉你如何创建和使用静态和共享(动态)库在UNIX环境下.
About Libraries
软件库是一个包含编译的代码和可能用到的数据的文件,可以被其他文件使用.它不能被运行.
Static Versus Shared Libraries in UNIX
(static library)静态库在程序编译之后可以被程序静态链接,作为可执行文件的一部分.换句话说它合并到可执行程序文件中.共享库(shared library)可以被动态链接,无论是在加载或者运行阶段,依赖于特有的系统.
Identifying Libraries
静态库文件以(.a)结尾.动态库以(.so)作为扩展,可以在后面添加版本号如(librt.so.1).所有类型的库都是以"lib"开头后面添加真实的名字命名的.例如标准的C++静态库是"libstdc++.a".
Creating a Static Library
1.创建timestuff.c和errors.c文件
2.编译c文件
gcc -c timestuff.c gcc -c errors.c
会生成两个.o文件
3.运行GNU archiver,ar,创建.a文件
ar rcs libutils.a timestuff.o errors.o
如果要添加新的文件进去也可用这条命令
4.生成后将libutils.a文件放入项目的./lib目录下,libutils.h文件放入项目的./include目录下.如何想要所有的项目都可以使用可以各自放入~目录下相关的./lib和./include目录下.
5.确保你的LIBRARY_PATH环境中包含你的静态库的路径,你的.bashrc文件中必须包含
LIBRARY_PATH="$LIBRARY_PATH:~/lib:"
export LIBRARY_PATH
保证你的gcc可以找到你常用的库文件地址,如果你想让你的库文件在标准库之前被搜索,可以用到以下命令
LIBRARY_PATH="~/lib:$LIBRARY_PATH"
export LIBRARY_PATH
6.确保包含你的头文件目录,你的.bashrc文件中必须包含
CPATH="~/include"
export CPATH
注意:不要将静态库和共享库放在同一个目录下
Using (Linking to) a Static Library
1.在你的程序中添加头文件
#include "utils.h"
2.去构建可执行程序:
gcc -o myprogram myprogram.c -lutils
如果没有修正CPATH:
gcc -o myprogram myprogram.c -lutils -I~/unix_demos/include
注意:同一个名字同一目录下动态库优先级大
如果没有修改LIBRARY_PATH,可以用以下
gcc -o myprogram myprogram.c -L~/unix_demos/lib -lutils
Creating a Shared Library
Shared Library Names
共享库将会有三个名字:
- libutils.so.1 -这个是它的soname
- libutils.so.1.0.1 -这个是文件的名字
- libutils.so -这个是编译器用的,也被叫链接名字
这三个文件之间的关系是这样的:
lrwxrwxrwx 1 root root 11 Aug 12 18:52 libacl.so -> liba l.so.1
lrwxrwxrwx 1 root root 15 Aug 12 18:51 libacl.so.1 -> liba l.so.1.1.0
-rwxr-xr-x 1 root root 31380 Aug 3 18:42 libacl.so.1.1.0
依次表示软链接
Steps to Create the Library
1.创建一个文件来创建共享库,名叫stuff.c
gcc -fPIC -g -Wall - stuff.c
-g 显示debugging 信息
-Wall 显示warning
-fPIC 告诉编译器产生与位置无关代码.则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
2.创建共享库libgoodstuff.so.1.0.1(真实名字),libgoodstuff.so.1(soname)
gcc -shared -Wl,-soname,libgoodstuff.so.1 -o libgoodstuff.so.1.0.1 stuff.o tools.o
-Wl 告诉链接编译器以逗号为分割
3.如果你是superuser,可以把文件放入/usr/lo al/lib,一般我们放入~/lib文件下,仅copy就行.
4.copy后执行下一条指令
ldconfig -n ~/lib
ldconfig是一个动态链接库管理命令,为了让动态链接库为系统所共享,还需运行动态链接库的管理命令–ldconfig。
-n ldconfig仅扫描命令行指定的目录,不扫描默认目录(/lib,/usr/lib),也不扫描配置文件/etc/ld.so.conf所列的目录.
然后建立实际名字文件和soname文件的软链接
ln -s libgoodstuff.so.1 libgoodstuff.so
5.如果之后库文件代码修改的话只需要将libutils.so.1.0.2复制到目录下,再次idconfig 后完成,文件链接如下.
libutils.so -> libutils.so.1
libutils.so.1 -> libutils.so.0.2
libutils.so.1.0.1
libutils.so.1.0.2
Using a Shared Library
可以使用以下命令去链接
gcc -o myprogram myprogram.c -L~/lib -lgoodstuff
gcc -o myprogram myprogram.c ~/lib/libgoodstuff.so
如果LIBRARY_PATH环境是有效的,则可执行
gcc -o myprogram myprogram.c -lgoodstuff
t通过ldd命令可以查看程序对共享库的依赖以及所在的文件,如果没有出现应有的共享库,则说明未找到相应共享库的位置.
如以下成功找到的例子
linux-gate.so.1 => (0x00a31000)
libgoodstuff.so.1 => ~/lib/libgoodstuff.so.1 (0x00 aa000)
libc.so.6 => /lib/libc.so.6 (0x00110000)
/lib/ld-linux.so.2 (0x00bd5000)
如果没有
linux-gate.so.1 => (0x00a31000)
libgoodstuff.so.1 => not found
libc.so.6 => /lib/libc.so.6 (0x00110000)
/lib/ld-linux.so.2 (0x00bd5000)
修改LD_LIBRARY_PATH环境变量
LD_LIBRARY_PATH="~/lib"
export LD_LIBRARY_PATH
或者
LD_RUN_PATH="~/lib"
export LD_RUN_PATH
Displaying the Contents of a Library
静态库可以用:
ar t <libraryname>
nm -s <libraryname>
动态库
nm -s --dynamic <libraryname>
也可以用readelf命令相关查看https://blog.csdn.net/yfldyxl/article/details/81566279.