1、静态库
1.1 准备好自己写好或下载的C文件和头文件(就像单片机添加一个模块的aston.c、aston.h),库里面没有主函数,只有被调用的函数
1.2 在原材料C和H同级文件目录下编写makefile(编译过程)
all:
gcc -c aston.c -o aston.o
ar -rc libaston.a aston.o
(1)首先使用gcc -c只编译不链接,生成.o文件,将aston.c编译生成 -o 指定名字的.o文件,改成你喜欢的名字都行;
GCC参数详解:博主:http://blog.sina.com.cn/s/blog_57295811010008pj.html
(2)然后使用ar工具进行打包成.a归档文件(需要原材料.o文件,-rc参数自己查)
ar也是系统编译工具中的一个可执行程序,专门用来制作静态库a文件
(3)库名不能随便乱起,一般是lib+库名称,标准化方便系统统一查找,后缀名是.a表示是一个归档文件(静态库)
(4)make执行makefile,生成了静态库
1.3 同级目录下创建主函数调用库(编译链接)
1.3.1 编译主函数 gcc test.c -o test -laston -L.
(1)编译链接test.c成指定的可执行文件名test,不使用-o将生成系统默认的a.out
(2)-laston,告诉链接器链接时候需要链接的库
(3)-L. 告诉链接器库所在的路径,放在系统默认寻找的路径下可以不用加,我们库被放在当前同级目录,所以用 一个点
细节:这一步编译将静态库里面的函数静态的编译进了test可执行文件,动态库没有编译进去
1.3.2 nm命令
(1)执行nm libaston.a,可以知道这个静态库里面由哪些.o文件组成,.o又包含了哪些具体函数名
2、动态库(引用静态库源文件)
2.1 创建一个动态链接库(编译链接过程)
all:
gcc -c aston.c -o aston.o -fPIC
gcc -o libaston.so aston.o -shared
(1) -fPIC 编译成位置无关码,因为将来运行时,是被操作系统动态加载的,被加载到什么地方是不一定的,因为动态库过程,可执行文件里面并没有将动态库编译进去,可执行文件运行需要使用动态库函数时,操作系统将整个动态库加载到内存,提供调用
(2)动态库制作使用的是gcc工具,-o指定名字 -shared (共享库方式链接,没有加-c就是编译链接)
2.2 编译主函数
2.2.1 编译主函数 gcc test.c -o test -laston -L.
(1)编译成功,但运行出错
错误原因:动态链接库运行时需要被加载(运行时环境在执行test程序的时候发现他动态链接了libaston.so,于是乎会去固定目录尝试加载libaston.so,如果加载失败则会打印以上错误信息。)
解决方法一:将libaston.so放到固定目录下就可以了,这个固定目录一般是/usr/lib目录。
cp libaston.so /usr/lib即可
解决方法二:使用环境变量LD_LIBRARY_PATH。操作系统在加载固定目录/usr/lib之前,会先去LD_LIBRARY_PATH这个环境变量所指定的目录下去寻找,如果找到就不用去/usr/lib下面找了,如果没找到再去/usr/lib下面找。所以解决方案就是将libaston.so所在的目录导出到环境变量LD_LIBRARY_PATH中即可。
总结:(1)上述都是在windows/ubuntu平台下做的测试,如果在开发板linux下,需要使用交叉编译工具,但是操作流程一样。
(2)动态静态库的区别,就是编译时是否将库函数编译进了可执行程序,一个是编译进去静态运行,一个是运行时将库加载到内存,动态运行
3、 ldd命令:作用是可以在一个使用了共享库的程序执行之前解析出这个程序使用了哪些共享库,并且查看这些共享库是否能被找到,能被解析(决定这个程序是否能正确执行)。