库的概念
Ø 库是一个二进制文件,包含的代码可被程序调用
Ø 标准C库、数学库、线程库……
Ø 库有源码,可下载后编译;也可以直接安装二进制包
Ø /lib /usr/lib 库
Ø 库是事先编译好的,可以复用的代码。
Ø 在OS上运行的程序基本上都要使用库。使用库可以提高 开发效率。
Ø Windows和Linux下库文件的格式不兼容
Ø Linux下包含静态库和共享库
静态库
在程序编译时候链接截断被连接到目标代码中,运行时候不在需要静态库。编译后体积较大。
共享库(动态库)
在程序编译时候并不会被马上链接到目标代码中,而是在执行阶段才被程序载入,因此编译后的可执行程序体积小,但是需要系统动态库存在。
| 了解 | 静态库 | 动态库 |
|---|---|---|
| Windows | .lib | .dll |
| Linux | .a | .so |
预处理 gcc a.c -E -o a.i 做宏替换,头文件展开,去除注释
编译 gcc a.i -S -o a.s 检查语法错误,将C语言编译生产汇编
汇编 gcc a.s -c -o a.o 将汇编编译成二进制机器码
链接 gcc a.o -o a.out 将所有二进制机器码文件.o和静态库文件.a统一链接生成可执行程序a.out
E i
S s
c o
静态库制作
静态库特点
~ 编译(链接)时把静态库中相关代码复制到可执行文件中
~程序中已包含代码,运行时不再需要静态库
~程序运行时无需加载库,运行速度更快
~占用更多磁盘和内存空间
~静态库升级后,程序需要重新编译链接
静态库创建
Ø 确定库中函数的功能、接口
Ø 编写库源码hello.c
1 //hello.c 2 #include <stdio.h> 3 void hello(void) 4 { 5 printf(“hello world\n”); 6 return; 7 }
Ø 编译生成目标文件
$ gcc -c hello.c -Wall
gcc -c hello.c -Wall
Ø 创建静态库 hello
$ ar crs libhello.a hello.o
ar crs libhello.a hello.o
Ø 查看库中符号信息
$nm libhello.a
nm libhello.a
hello.o:
0000000 T hello
U puts
链接静态库
Ø 编写应用程序test.c
1 //test.c 2 #include <stdio.h> 3 4 void hello(void); 5 int main() 6 { 7 hello(); 8 return 0; 9 }
Ø 编译test.c 并链接静态库libhello.a
$ gcc -o test test.c -L. -lhello
gcc -o test test.c -L. -lhello
|
gcc |
-o | test | test.c | -L | . | -l | Hello |
| gcc编译器 | 重命名选项 | 重命名 | .c文件 | 链接库选项 | 链接库路径 | 链接库标识符 | 库名 |
$ ./test
hello world
共享库制作
共享库特点
~ 编译(链接)时仅记录用到哪个共享库中的哪个符号,不 复制共享库中相关代码
~ 程序不包含库中代码,尺寸小
~ 多个程序可共享同一个库
~ 程序运行时需要加载库
~ 库升级方便,无需重新编译程序
~ 使用更加广泛
共享库创建
1、确定库中函数的功能、接口
2、编写库源码hello.c bye.c
1 //hello.c 2 #include <stdio.h> 3 void hello(void) 4 { 5 printf(“hello world\n”); 6 return; 7 } 8 9 //bye.c 10 #include <stdio.h> 11 void hello(void) 12 { 13 printf(“bye\n”); 14 return; 15 }
3、 编译生成目标文件
$ gcc -c -fPIC hello.c bye.c -Wall
gcc -c -fPIC hello.c bye.c -Wall
-fpic编译为位置独立的代码
4、 创建共享库 common
$ gcc -shared -o libcommon.so.1 hello.o bye.o
gcc -shared -o libcommon.so.1 hello.o bye.o
-shared指定生成动态库 lib<库名>.so.<版本>
5、 为共享库文件创建链接文件
$ ln -s libcommon.so.1 libcommon.so
ln -s libcommon.so.1 libcommon.so
1)在虚拟机与物理机的共享文件目录中,无法创建符号链接文件
2)将 libcommon.so.1 复制到虚拟机家目录下,就可以创建符号链接了
6、 符号链接文件命名规则
lib<库名>.so
链接共享库
1、编写应用程序 test.c
1 #commin.h 2 void hello(void); 3 void bye(void);
1 //test.c 2 3 #include <stdio.h> 4 #include "common.h" 5 int main() 6 { 7 hello(); 8 bye(); 9 return 0; 10 }
2、 编译 test.c 并链接共享库 libcommon.so
$ gcc -o test test.c -L. -lcommon
gcc -o test test.c -L . -l common
1)默认情况下先找共享库
2)如果共享库存在,则链接共享库
3)如果共享库不存在,则寻找静态库
4)如果静态库存在,则链接静态库
5)如果静态库不存在,则报错
6)若加上 -static 选项,则直接链接静态库
加载共享库
1、执行程序
$ ./test
./test: error while loading shared libraries: libcommon.so cannot open shared object file : No such file or directory
2、添加共享库的加载路径
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
$ ./test
hello world
bye!
如何找到共享库
Ø 为了让系统能找到要加载的共享库,有四种方法 :
1、把库拷贝到/usr/lib和/lib目录下 不推荐
2、在LD_LIBRARY_PATH环境变量中添加库所在路径 推荐(但是是一次性的)
3、添加/etc/ld.so.conf.d/*.conf文件,执行ldconfig刷新 推荐(永久性的)
1)在/etc/ld.so.conf.d/目录下,新建一个*.conf文件
如:touch my.conf
2)在 my.conf 添加路径
如 /mnt/htgf/abc
3)在终端中执行 sudo ldconfig 命令刷新
4、或者 sudo vim /etc/bash.bashrc 推荐(永久性的)
在文件末尾增加 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/tmp
保存退出,重启终端,此时在此执行./a.out正常显示。
浙公网安备 33010602011771号