您的位置:首页 > 运维架构 > Linux

【Linux/C】如何编译和使用库文件

2016-06-21 20:55 323 查看

1. 库文件分类

库文件可以分为两类,静态库和动态库。

链接静态库的程序特点:1. 程序较大;2.不容易升级;3.容易部署

链接动态库的程序特点:1. 程序较小;2.容易升级;3.不容易部署

2. 存档文件(静态库)

存档文件(Archive),也就是静态库,就是一系列目标文件的集合(大致相当于windows下的*.LIB文件)。当你提供一个存档文件给链接器的时候,链接器会在存档文件中寻找所需的目标文件,提取他们,然后与链接单个的目标文件一样链接到你的程序当中。

可以使用ar命令创建存档文件。存档文件一般以.a作为后缀名,而目标文件一般以.o为后缀名。例如以下命令可以将test1.o和test2.o合并成一个libtest.a文件。(#是表示root用户提示符,不用输入)

# ar cr libtest.a test1.o test2.o


cr标志告诉ar命令产生存档文件。现在可以使用gcc或者g++的-ltest选项链接目标文件。

3. 共享库

共享库(或者称动态链接库)与静态库相同的地方是它也是一系列目标文件的集合。不过,这两者都很重要的不同之处。

动态库和静态库最本质的差别是:当一个动态链接库被链接到一个程序的时候,程序的最终可执行文件并不真的包含动态链接库中的代码。而是在可执行文件当中包含一个动态链接库的引用。如果系统中有多个程序链接到同一个动态链接库,他们都会引用这个库。因此,这个库是多个程序共享的,称为“共享库”。

另一个重要区别是:动态链接库并不仅仅是一系列目标文件的集合,链接器会在这些目标文件当中选择所需的文件以匹配未定义的引用。生成动态链接库的时候,所有目标文件被合成一个单独的目标文件,从而使链接到这个库的程序总能包含库中的全部代码,而不仅仅是所需要的部分。

要创建共享库,必须在编译那些用于生成共享库的对象时为编译器指定-fPIC选项,例如:

# gcc -c -fpic  test1.c


这条指令将创建目标文件,选项-fpic告诉编译器你将要用test1.o文件作为共享库的一部分。PIC是(Position-Independent Code的缩写)。创建目标文件后,可以使用以下指令把得到的目标文件合并成一个共享库。

# gcc -shared -fpic -o libtest.so test1.o test2.o


-share选项告诉编译器生成共享库而不是普通的可执行文件。共享库使用*.so作为后缀名(so表示shared object)。一般在文件名前面加lib表示这是一个库文件。

假设静态库文件(如libtest.a)和动态库(libtest.so)文件同时存在,那么链接器必须选择一个进行链接,链接器会依次搜索每个文件夹(首先搜索-L选项指定的文件夹,然后搜索系统默认搜索路径)。当链接器找到了包含库文件的目录,那么就停止搜索。如果两种库文件在同一个目录下,除非你专门指定,否则链接器优先链接动态链接库。你可以使用-static选项指定链接器链接静态库。如:

#gcc -static -o app app.o -L. –ltest

使用ldd指令可以查看有哪些动态库与程序建立了动态链接。

4. 使用LD_LIBRARY_PATH

当链接一个动态库到一个程序的时候,链接器并不会将动态库的完整路径添加到可执行文件中。链接器仅将动态库的名字添加到可执行文件当中。程序实际运行的时候,系统会搜索并加载库文件。系统搜索路径为/lib和/usr/lib。默认情况下,如果你的程序链接了一个不在这两个文件夹当中的动态库,那么显然系统找不到动态库文件,系统拒绝执行程序。解决系统找不到动态库文件的办法有三个:

将你的动态库文件添加到上述的两个文件夹,这是很显然的。

链接程序和库文件的时候,使用-Wl,-rpath选项,例如:

gcc -o app app.o -L. -ltest -Wl,-rpath,/usr/local/lib

这样,系统运行程序时,会去/usr/local/lib目录下寻找动态库文件。

设置LD_LIBRARY_PATH环境变量

设置办法如同PATH一样,系统会在这个变量设置的路径中依次寻找所需

要的库文件。

参考资料:

[1].Advanced Linux programming
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: