工程中很多时候都会使用别人经过验证的库,或者第三方提供的库,现在很多工程中实际开发中是以库的形式对外发布,库主要分为静态库和动态库。
静态库: 编译时候加载进目标文件内部。程序运行时不需要该库。命名libxxx.a
动态库: 编译时链接至目标文件,只在目标文件内部指出连接地址。程序运行时加载动态库。 命名libxxx.so;
实例讲解:
本章实现 加法 、减法静态库,然后实现乘法、除法动态库。然后在main中调用。 现将每个文件代码列出如下:
注意:源代码拷贝编译可能通不过,原因是有些括号是中文符号。改之则可。
//add.c int addNum(int a, int b) { return (a+b); }
//Sub.c int subNum(int a,int b) { return(a -b); }
//mul.c int mulNum(int a ,int b) { return(a*b); }
//div.c int divNum(int a,int b) { return(a/b); }
//main.c #include<stdio.h> #include<stdlib.h> #include"common.h" //编译时候需要找到函数声明 int main() { int a = 4; int b = 2; printf("a+b = %d\n",addNum(a,b) ); printf("a-b = %d\n",subNum(a,b) ); printf("a*b = %d\n",mulNum(a,b) ); printf("a*b = %d\n",divNum(a,b) ); }
//common.h extern int addNum (int a, int b); extern int subNum(int a,int b); extern int mulNum(int a ,int b); extern int divNum(int a,int b);
(1) 静态库的生成
1> 编译
$ gcc -c add.c sub.c
2> 打包
为了在可执行程序生成过程中,链接时正确找到库文件,静态库必须按照 lib[name].a 的规则命名。
ar 命令 用于打包
-r 表示文件添加进文件包
-s 创建链接库索引,该索引在程序链接时候使用 ranlib 命令也可以创建索引
$ ar -rs libaddsub.a add.o sub.o
或者
$ ar r libstack.a stack.o push.o pop.o is_empty.o
$ ranlib libstack.a
(2)动态库的生成
1> 编译
组成动态库的目标文件和一般的目标文件有所不同,在编译时要加-fPIC选项 -f后面跟一些编译选项,PIC 是其中一种,表示生成位置无关代码。
$ gcc -c -fPIC div.c mul.c
2> 生成动态库
$ gcc div.o mul.o -shared -o libmuldiv.so
以上两步可以合在一起 $ gcc div.c mul.c -fPIC -shared -o libmuldiv.so
(3)可执行文件的生成
gcc 编译选项参数介绍
-L 表示去哪里寻找 库文件 注: 即使在默认路径 也要指定路径
-I 表示去哪里寻找头文件
-print-search-dirs 参数查看编译器默认会寻找的目录
gcc main.c -L. -laddsub -lmuldiv -o main
运行./main 提示找不到动态库libmuldiv.so 。
这是因为 linux的可执行程序在执行的时候默认是先搜索/lib和/usr/lib这两个目录,然后按照/etc/ld.so.conf里面的配置搜索绝对路径。同时,Linux也提供了环境变量LD_LIBRARY_PATH供用户选择使用,用户可以通过设定它来查找除默认路径之外的其他路径,如:LD_LIBRARY_PATH =/work/lib:$(LD_LIBRARY_PATH),并且LD_LIBRARY_PATH优先于系统默认路径之前查找。
解决方法:
第一种 :cp libmuldiv.so /usr/lib 程序安装时候一般会存放于目录
第二种 :修改LD_LIBRARY_PATH 不推荐使用
第三种 :修改/etc/ld.so.conf 程序调试时候建议使用 一次更改一直有效
第四种 :创建一个连接到/usr/lib
(4)ldd ,nm 命令
使用ldd命令来查看执行文件依赖于哪些库
要查看一个动态库包含哪些函数 使用nm 命令。
(5) 本例makefile
通过这个例子 大家可以学到如何在makefile中生成静态库或者动态库 。本例已经才ubuntu12.04 中测试验证过。
#***************************************************************************** # # Author : wolfRickWang # Date : 2013/7/17 星期三 13:27:22 # #****************************************************************************/ SHELL = /bin/sh CC = gcc AR = ar CFLAGS = -c EXECUTABLE = main EXECUTLIB = libmuldiv.so EXECUTSLIB = libaddsub.a SOURCES = main.c SLIBSOURCES = add.c sub.c SLIBOBJECTS = $(SLIBSOURCES:.c=.o) LIBSOURCES = mul.c div.c $(EXECUTABLE): $(SOURCES) $(EXECUTLIB) $(EXECUTSLIB) $(CC) $(SOURCES) -L. -laddsub -lmuldiv -o $@ $(EXECUTLIB) : $(LIBSOURCES) $(CC) $(LIBSOURCES) -fPIC -shared -o $@ $(EXECUTSLIB):$(SLIBOBJECTS) $(AR) -rs $@ $(SLIBOBJECTS) %.o: %.c $(CC) $(CFLAGS) $< -o $@ install: cp $(EXECUTLIB) /usr/lib clean: rm -f *.o $(EXECUTABLE) $(EXECUTLIB) $(EXECUTSLIB) .PHONY: clean install