Linux的库文件分为两种,一种是静态库(.a文件, 相当于Windows下的.lib),另一种是动态库(.so文件, 相当于Windows下的.dll)。编译时,一种是把编译的.o文件(相当于Windows下的.obj)和静态库的.a文件一起链接成可执行文件,另一种就是只编译链接.o文件,当运行时需要动态库的函数时再载入动态库。
编译方法
1. 静态库
gcc -c -I/usr/local/include -o func.o func.c #将func.c编译成目标文件func.o ar -rs libfunc.a func.o #将目标文件func.o加入libfunc.a静态库 gcc -I/usr/local/include -L. -o main main.c -lfunc -static #链接libfunc.a生成main
链接静态库到可执行文件也可以使用以下命令:
gcc -I/usr/local/include -L. -o main main.c -lfunc
或者:
gcc -I/usr/local/include libfunc.a -o main main.c
ar是archive的缩写,ar可以同时将多个目标文件(.o文件)加入一个静态库.a文件,比如:
ar -rc libfunc.a func1.o func2.o
2. 动态库(共享库)
gcc -I/usr/local/include -shared -o libfunc.so func.c #将func.c编译成动态库libfunc.so gcc -I/usr/local/include -L. -o main main.c -lfunc #链接libfunc.so生成main
运行main时需要确保动态库libfunc.so在系统默认动态库路径或LD_LIBRARY_PATH变量路径下,或者参考我的这篇文章设置动态库路径。
查看一个可执行文件需要依赖的动态库可以使用下面的命令:
ldd main
比如,查看ln命令需要依赖哪些动态库:
ldd /bin/ln linux-gate.so.1 => (0x00832000) libc.so.6 => /lib/libc.so.6 (0x00110000) /lib/ld-linux.so.2 (0x006a9000)
需要注意,Linux下lib库有固定的命名格式,静态库为:libXXX.a;动态库为:libXXX.so.major.minor,其中major为主版本号,minor为副版本号,通常动态库需要用ln –s创建一个指向其的链接libXXX.so供程序调用。
另外,gcc的链接参数-l需要放在所有输入文件名的后面,否则会编译失败。
附:静态库的创建与操作:
ar [drqtpmx] [options] archive.a object.o
-d: 从静态库中删除文件objfile
-r: 替换或插入objfile
-q: quick append, 加入objfile without checking
-t: type打印静态库中的成员文件列表
-p: print指定objfile
-m: move移动archive中的成员
-x: extract从静态库文件中抽取文件objfile
-c: 创建静态库文件
-s: 重置静态库文件索引
举例:释放静态库文件
ar -x /usr/lib/libc.a
举例:创建静态库文件
ar -scr libfunc.a func1.o func2.o