目录
gcc工作流程
静态库的生成和使用(该部分使用g++进行代码的编译。 若使用gcc,也类似)
动态库的制作和使用(此处用gcc,g++类似)
动态库的命名规则
动态库的制作
动态库的使用
动态库和静态库的优缺点
静态库的优点
静态库的缺点
动态库的优点
动态库的缺点
为什么使用makefile?
1)第一步是先对源代码进行预处理,具体处理如:去掉注释、在使用宏的地方替换具体宏定义的值、将头文件内容展开等。可使用以下代码进行这一步(test.cpp是一个用来测试的c文件)。
gcc test.c -E -o test.i
2)第二步是对预处理后的源代码进行编译,使其编译为汇编代码。可使用以下代码进行这一步。
gcc test.i -S -o test.s
3)第三步是对汇编代码进行汇编使其变为机器代码(即0,1)。可使用以下代码进行这一步。
gcc test.s -c test.o
4)将目标代码与库代码,其他目标代码以及启动代码进行链接,生成最终的可执行程序。
注意:平常使用如下代码,即按顺序执行上述四步。
gcc test.c -o test
1)生成:使用ar命令及其rcs参数进行生成。比如我有四个文件分别实现了加减乘除,并有一个头文件声明了这四个函数。
现在要生成一个静态库,如何生成?
第一步先执行:g++ -c add.cpp divide.cpp multiply.cpp substract.cpp
第二步再执行:ar rcs libcal.a add.o divide.o multiply.o substract.o
即生成了libcal.a这个静态库。其中lib是前缀,而cal是静态库的名字。
2)使用:编译某文件时,若使用到该静态库,则使用g++参数的-l 告诉系统静态库的名称,即cal,使用-L参数告诉系统静态库所处的位置,即可。
1)Linux:libxxx.so
lib:前缀(固定)
xxx:库的名字,自己起
.so:后缀(固定)
在Linux下是一个可执行文件
2)Windows:libxxx.dll
1)gcc得到.o文件,得到和位置无关的代码
gcc -c -fpic/fPIC a.c b.c
2)gcc得到动态库
gcc -shared a.o b.o -o libcal.so
使用方式和静态库一样,但注意动态库并不是在程序链接阶段进行链接的,而是在程序启动之后动态库被加载到内存,使用的时候会进行动态链接。
通过ldd(list dynamic dependencies)命令检查动态库的依赖关系。
注意:在使用前需要将动态库的绝对路径告诉系统,可以通过设置环境变量达到该目的。
静态链接和动态链接
静态链接和动态链接的区别在于链接的时机不一样,静态链接的链接是在形成可执行文件时,而动态链接的链接是在程序运行期间。但注意,在形成可执行文件时,若发现有调用动态库的函数,则不对这个函数进行重定位,而把这个过程留到装载时再进行。
1)在可执行程序中已经具备了所有执行程序所需要的任何东西,在执行的时候运行速度快。
2)发布程序时无需提供静态库,移植方便。
1)浪费空间。每个可执行程序都有静态库的副本。
2)更新不方便。因为每当库函数的代码修改了,这个时候就需要重新进行编译链接形成可执行程序。
1)省空间。即使需要每个程序都依赖同一个库,但是该库不会像静态链接那样在内存中存在多份副本,而是这多个程序在执行时共享同一份副本;
2)更新方便。更新时只需要替换原来的目标文件,而无需将所有的程序再重新链接一遍。
1)执行速度慢。因为把链接推迟到了程序运行时,所以每次执行程序都需要进行链接,所以性能会有一定损失。
2)发布程序时需要提供动态库,移植不方便。
因为makefile降低了程序员的编译工作量(写好makefile文件后,每次编译只需make即可),而且makefile提供了一些机制确保编译能有序执行。