Linux系统上库文件的生成与使用(静态库和动态库)

发布于:2022-11-09 ⋅ 阅读:(9) ⋅ 点赞:(0) ⋅ 评论:(0)

目录

1、什么是库文件?

2、静态库的生成与使用

2.1、生成 .o 文件

2.2、创建静态库

2.3、使用静态库

3、动态(共享)库的生成与使用

3.1、生成 .o 文件

3.2、生成动态库文件

3.3、使用动态库

4、静态库与动态库的区别


1、什么是库文件?

        库是一组预先编译好的方法的集合,是计算机上的一类文件,提供给使用者一些开箱即用的变量、函数或类。库文件分为静态库动态库,静态库和动态库的区别体现在程序的链接阶段。
        一般来说,Windows静态库文件扩展名 .lib动态库文件扩展名 .dll (Dynamic-Link Libraries);Linux静态库扩展名.a动态库扩展名.so (Shared Object)。内容一样,都是将函数封装,编译后生成.o文件,将所有 .o 文件合并生成库文件,再将供自己或他人调用。好处在于编译后的库文件的源代码被加密,使用者看不到,可保密。
        Linux系统存储的库的位置一般在:/lib 和 /usr/lib。 在 64 位的系统上有些库也可能被存储在/usr/lib64 下。库的头文件一般会被存储在 /usr/include 下或其子目录下。
        Linux库有两种,一种是静态库,其命令规则为 libxxx.a;一种是共享库,其命令规则为 libxxx.so

2、静态库的生成与使用

        静态库是.o 文件打包的结果,.o文件的数量可以是1个,也可以是多个。生成的过程需要使用 ar 工具来操作。

测试文件:

add.c:

max.c:

foo.h:

main.c:

2.1、生成 .o 文件

        使用命令gcc  -c  源文件序列

        命令的用法是多种多样的,可以分步经 预处理编译汇编 生成 .o 文件,也可以直接使用 gcc  -c  源文件名,一步生成 .o 文件。

        例如,使用命令 gcc  -c  add.c  max.c  ,一步生成两个文件的 .o 文件。

2.2、创建静态库

        使用命令ar  crv  lib库名.a  add.o  max.o

        例如,使用 ar  crv  libfoo.a  add.o  max.o,生成库名为libfoo.a,包含addmax两种方法的静态库。

        c 参数是创建库;r 参数是将方法添加到库中;v 参数显示详细过程。

2.3、使用静态库

        使用命令gcc  -o  main  main.c  -L  库文件所在路径  -l  库名

        在当前程序中使用静态库的方法,就是使用 gcc  -o  生成的可执行程序名  当前程序  -L  库文件所在路径  -l  库名

        ● -L  指定库文件所在路径 

        ● -l  指定库名(库名是libxxx.a中的xxx,无lib.a)

        例如,gcc  -o  main  main.c  -L  .  -l  foo,目标库文件就在当前目录下,所以路径为 . ,库文件名在去除lib.a后为 foo。

         此时,成功生成了可执行程序。

         执行程序后,发现程序结果符合预期,所以使用的库文件是正确的,并且成功使用了。

3、动态(共享)库的生成与使用

        动态库的测试文件除main程序外与静态库的测试文件相同:add.c、max.c、foo.h。

main.c:

3.1、生成 .o 文件

        gcc  -c  add.c  max.c

3.2、生成动态库文件

        使用命令gcc  -shared  -fPIC  -o  libfoo.so  add.o  max.o

        使用如上命令,就可以根据add.o和max.o文件,生成名为 libfoo.so 的动态库文件。

3.3、使用动态库

        使用命令gcc  -o  main  main.c  -L  .  -l  foo

        -L还是指定库文件所在路径,-l 指定库文件名。但是在命令使用前,我们需要了解一件事情,就是系统对动态库的链接,默认是在 /usr/lib 目录下的,意思就是就算此时我们指定了库文件所在路径,系统还是会去 /usr/lib 目录下寻找动态库文件。此时,有两种解决方案:

        1、将自制的动态库文件移动到 /usr/lib 目录下。

        此时,在使用动态库时就不用指定库文件所在路径了,但需要注意不能库文件名与 /usr/lib 目录下原有动态库文件重名

         此时,使用 gcc  -o  main  main.c  -l  foo 命令后,成功生成可执行文件。

         在执行文件后,程序结果正确,所以动态库生成与使用成功。

        2、修改环境变量,使可在当前目录下链接动态库。

        命令export  LD_LIBRARY_PATH=.

        此时,设置环境变量后,先将动态库文件从 /usr/lib 目录下移动回来。

        再使用 gcc  -o  main  main.c  -L  .  -l  foo 命令,使用动态库。

         新生成的main可执行程序将原main程序覆盖。

         ./main程序执行正确,libfoo.so动态库文件使用成功。

        两个额外命令:删除指定环境变量:unset LD_LIBRARY_PATH;查看环境变量的值:echo $LD_LIBRARY_PATH。

3.4、查看可执行程序依赖的动态库

        命令:ldd  可执行程序名。

 4、静态库与动态库的区别

        每一个程序在使用静态库时,都会将静态库文件拷贝一份添加到自身。如果有多个程序都要使用该静态库文件时,都会给自身添加一份拷贝,这就导致会产生空间浪费。在源文件较少时不明显,但如果在一个项目中,静态库文件本身就比较大,并且使用该静态库文件的源程序很多,这就会造成大量内存浪费。

        而动态库文件在被使用时,会对所有想使用该动态库的源程序添加一个标记,在程序执行时再链接动态库文件使用。这就是动态库的优点,也是动态库被称为共享库的原因。