库文件简介
库文件其实就是已经编译好的函数的二进制文件,在编译工程的时候可以直接编译到可执行文件中,这些函数不需要重新编译!
Gcc --> 编译过程
库文件作用:
- 保护程序员知识产权
- 节省编译时间
Linux下支持静态库,动态库(共享库)。系统的库文件一般存放在 /lib /usr/lib
注意:main函数不能被编译到库文件!
- 库文件
- 静态库
1)命名格式: libxxx.a --> libjpeg.a (名字为jpeg的静态库文件)
==> lib : 静态库的前缀名
==> jpeg : 静态库名
==> .a : 静态库的后缀名
2)静态库的编译
==> 编译命令: ar -cr 静态库全称 依赖的文件(二进制文件:xx.o)
==> 库文件编译其实就是把编译过的二进制文件封装到一个特殊的二进制文件中。
·把源文件(xx.c)编译生成二进制文件(xx.o)
gcc -c fun.c -o fun.o
·把二进制文件处理得到静态库文件
ar -cr libfun.a fun.o
如果有多个.o 文件需要得到库文件,那就把他们都放在ar 命令的后面
==> ar -cr libfun.a fun.o 1.o 2.o (把fun.o, 1.o, 2.o 处理得到一个静态库文件)
- 使用静态库编译生成最终的程序
==> gcc main.c libfun.a -o myproject
例子:编译一个C语言工程,在C语言工程中存在 main.c , fun.c, usr.c, fun.h 现在编译这个工程!
==> 直接编译所有源代码: gcc main.c fun.c usr.c -o main (编译速度慢)
==> 把功能函数编译生成静态库文件,然后把静态库与main.c一起编译!
·把功能函数编译生成 .o
把功能函数编译生成 .o
把二进制文件生成静态库文件
编译main.c 和 libfun.a 得到可执行文件
注意事项:
在编译的时候默认是把头文件 fun.h 和源文件 fun.c 是放在同一个路径下的,如果头文件和源文件不在同一个路径下,那么编译的时候会报错!
==> 头文件声明 #include <stdio.h> || #include “stdio.h”
<> : 表示编译器直接从系统默认的头文件路径下去找 /usr/include
“” : 表示系统首先从当前路径下去找,如果找不到,那就去系统默认的路径下去找!
解决方案:
·把头文件放到系统默认的头文件路径 /usr/include (不建议这么做!)
·在编译的时候添加参数指定头文件路径! (建议这么做!)
==> gcc -c fun.c -o fun.o -I ./include
静态库的使用方法
main.c与静态库一起编译!
编译的时候指定连接到静态库
==> gcc main.c -o main3 -I ./include -L ./ -lfun
==> -I ./include : 指明头文件在当前路径下的include目录下
==> -L ./ : 指定库文件在当前路径下
==> -lfun : 编译的时候链接到库文件,文件名叫 fun
==> 这种编译方法得到的可执行文件与其他方式的可执行文件完全一致!
动态库(共享库)
- Linux下的动态库 libxxx.so
==> lib : 动态库的前缀名
==> xxx : 动态库的名字
==> .so : 动态库的后缀名
例如: libjpeg.so.9 ==> 这个是jpeg的动态库, .9表示版本号
- 动态库的编译
·先把源文件 (xx.c) 编译生成二进制文(xx.o)
==> gcc -c fun.c -o fun.o -fPIC (-fPIC表示生成与位置无关代码,可以任意跳转)
==> gcc -c usr.c -o usr.o -fPIC
·然后将编译好的二进制文件编译生成动态库
==> gcc -fPIC -shared -o libmyfun.so usr.o fun.o
动态库的使用
·将动态库与main.c 一起编译
编译的时候指定链接到库文件的路径与库文件名
==> 运行动态库编译生成的文件!
解决方案:
1)将生成的动态库放到系统默认的库文件(/lib, /usr/lib)路径下。那在执行可执行程序时会自动链接到这个库! (一般不建议这么做)
2)执行动态库编译生成的可执行程序时,可以修改环境变量中的库文件路径
==> LD_LIBRARY_PATH
==> export LD_LIBRARY_PATH=./
总结:
- 静态库与动态库都是存放功能函数的二进制的程序片段,都不能直接运行。
- 静态库与动态库在编译的时候不能把main函数编译进去。
- 静态库与动态库的区别
- 静态库编译的可执行文件比价大,动态库编译的可执行文件比较小。
- 静态库工程编译的可执行文件执行的时候不需要依赖其他文件!
动态库工程编译的可执行文件执行的时候必须要跟动态库文件一起使用!
4,动态库和静态库都是由 .o 文件处理得到的,但是静态库的 .o 文件与动态库的 .o 文件不能混淆使用!
5,在编译库文件和编译最终的可执行文件时,他们用到的编译工具链必须要一致!否则会编译失败!
(例如:在编译 .c到 .o的时候,使用 gcc工具链,在编译.o 到库文件的时候使用交叉工具链(arm-linux-ar , arm-linux-gcc )就会出现错误!)