一、静态库的制作 1.静态库制作步骤:静态库和动态库是两种共享程序代码的方式,它们的区别是:静态库在程序的链接阶段被复制到程序中,和程序运行的时候没有关系;动态库在链接阶段没有被复制到程序中,而是程序运行时由系统动态加载到内存中供程序调用。
在命名方式上, 静态库以.a结尾,动态库以.so结尾。
2.首先回顾一下C语言代码编译的4个环节:
- 编写或准备库的源代码;
- 将源代码.c文件编译生成.o文件;
- 使用ar命令创建静态库。
| 步骤 | 作用 | 产物 | 指令 |
|---|---|---|---|
| 预处理 | 展开头文件/宏定义/去掉注释/条件编译 | test.i main.i | gcc -E main.c main.i |
| 编译 | 检查语法,生成汇编 | test.s main.s | gcc -S main.i -o main.s |
| 汇编 | 汇编代码转换机器码 | test.o main.o | gcc -c main.s -o main.o |
| 链接 | 链接到一起生成可执行程序 | a.out | 链接动态库和静态库 |
#includevoid mylib_print(void); void mylib_print(void) { printf("mylib_printn"); }
(1)生成汇编文件
gcc -c mylib.c
(2)使用ar命令创建静态库
这里需要注意以下两个区别,库文件名都是以lib开头。
libmylib.a:库文件名
mylib:库名
ar cr libmylib.a mylib.o
(3)链接静态库
编写main.c测试程序
#includevoid mylib_print(void); int main(int argc, char **argv) { mylib_print(); return 0; }
使用-l指定库名,-L指定库路径链接静态库,执行以下指令后生成a.out可执行文件。
说明:gcc main.c -l[库名] -L [库路径] gcc main.c -lmylib -L .二、动态库的制作 1.静态库制作步骤:
2.以制作mylib.so为例子
- 编写或准备库的源代码;
- 将源代码.c文件编译生成.o文件;
- 使用ar命令创建静态库。
编写mylib.c源代码如下所示:
#includevoid mylib_print(void); void mylib_print(void) { printf("mylib_printn"); }
(1)生成汇编文件,其中-fpic生成是与位置无关的代码,便于其他代码调用。
gcc -c -fpic mylib.c
(2)使用gcc命令创建静态库,得到libmylib.so动态库。
gcc -shared -o libmylib.so mylib.o
(3)链接动态库 ,系统默认会在/lib或者/usr/lib去找库文件,或者在编译的时候指定库的路径。
编写main.c测试程序
#includevoid mylib_print(void); int main(int argc, char **argv) { mylib_print(); return 0; }
使用-l指定动态库名,-L指定动态库路径,执行以下指令后生成a.out可执行文件。-L .表示在当前目录下去查找。
说明:gcc main.c -l[库名] -L [库路径] gcc main.c -lmylib -L .
执行生成的a.out文件会提示找不到共享库的信息,是因为我们没有指定动态库的路径。
tianyu@ubuntu:/home/1.lib_demo/1.shared_lib$ ls a.out libmylib.so main.c mylib.c mylib.o tianyu@ubuntu:/home/1.lib_demo/1.shared_lib$ ./a.out ./a.out: error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or directory
有三种方法可以解决这个问题:
(1)将生成的动态库拷贝到/lib或者/usr/lib里面去,因为系统会默认去这两个路径下寻找;
(2)把我们的动态库所在的路径添加到环境变量里面去,比如我们动态库所在的路径为/home/test,我们就可以这样添加。该方法只针对当前终端有效。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/test
(3) 修改ubuntu下的配置文件/etc/ld.so.conf,我们在这个配置文件里面加入动态库所在的位置,然后使用命令ldconfig更新目录。
添加完动态库路径后,执行a.out就能够运行程序了。



