Makefile(6)------Makefile库的生成和使用+Makefile的执行过程

插播!插播!插播!亲爱的朋友们,我们的Makefile课程上线啦!感兴趣的小伙伴可以去下面的链接学习哦~

https://edu.csdn.net/course/detail/39264

一、Makefile库的生成和使用

1. 静态库

静态库又称为文档文件,是多个.o文件的集合,linux中静态库文件的后缀为".a"。我们将.o文件以一种特定的方式打包成一个单独的文件,并且在链接成可执行文件时,从这个单独的文件中“拷贝”自己需要的内容到最终的可执行文件中,这个单独的文件称为静态库。

举例说明:重新使用上述计算机例子为例:

add.c

#include

void add_init()
{
        printf("add operation  init\n");
}

add.h

#ifndef _ADD_H
#define _ADD_H

void add_init();

#endif

operation.c

#include
#include "add.h"

int main()
{
        printf("operation beginning\n");
        add_init();
        return 0;
}

(1)编译静态库,假设要将add.o编译为静态库,只需要对.o文件执行以下命令:

生成.o文件

gcc  -o  add.o  operation.o -c add.c operation.c

生成静态库add.a

ar rcs  libadd.a  add.o

(2)链接静态库,在上面得到libadd.a和operation.o文件后,将这两个文件链接起来:

gcc  -o test  operation.o  -L./ -ladd

-L./表明库文件位置在当前位置

-ladd表示链接libadd.a文件,使用“-l"参数时,前缀”lib“和后缀“.a"需要省略

2. 动态库

动态库是一种可以在运行时被加载的共享库,在程序启动时不会被完全加载进内存,仅有一个映射表,然后在需要使用库中函数或变量时再去加载,这样可以减小程序的内存占用。在 Linux 系统中,动态库以 .so 的后缀名为扩展名,也称为共享对象。相比于静态库,动态库的优点是可以被多个进程共享,从而减少重复的内存占用和磁盘空间占用,同时动态库也更加灵活,可以在运行时动态加载和卸载。在 Makefile 中,通过 -shared 选项可以将一组目标文件编译成动态库。

举例说明:重新使用上述计算机例子为例

(1)编译动态库,只需要在编译选项中加入-shared选项即可

gcc   -fPIC  -shared   add.c  -o  libadd.so

可见libadd.so依赖于add.c文件,使用-fPIC选项可以生成位置独立的代码,从而使得库可以被动态加载。

(2)链接动态库,在Makefile中需要指定需要链接得库文件和路径,并使用-l选项来指定依赖的库文件,-L选项指定了库文件路径。

gcc  operation.c  -L./   -ladd -o  test

二、Makefile的执行过程

1. 执行过程解析

make在执行时,可通过一个命名为Makefile的文件告诉make以何种方式编译源代码和链接程序。当对工程中的若干源文件进行修改时,make通过比较对应文件(规则的目标和依赖)的最后修改时间,自动根据修改情况完成源文件的对应.o文件的更新,库文件的更新,最终可执行程序的更新。而且还可以通过make的命令行选项来指定需要重新编译的文件。

2. 依赖关系解析

默认情况下,make执行的是Makefile的第一个规则,此规则的第一个目标称为终极目标,也就是一个Makefile最终需要更新或者创建的目标。当修改了任何 C 源文件或者头文件后,执行 make 将会重建终极目标。

当在 shell 提示符下输入“make”命令以后。make 读取当前目录下的 Makefile 文 件,并将 Makefile 文件中的第一个目标作为其执行的“默认目标”,开始处理第一个规则。

在我们的例子中,第一个规则就是目标“test”所在的规则。规则描述了“test”的依赖关系,并定义了链接.o 文件生成目标“test”的命令; make 在执行这个规则所定义的命令之前,首先处理目标“test”的所有的依赖文件(例子中 的那些.o 文件)的更新规则(以这些.o 文件为目标的规则)。对这些.o 文件为目标的规则处理有下列三种情况:

第一: 目标.o 文件不存在,使用其描述规则创建它;

第二: 目标.o 文件存在,目标.o 文件所依赖的.c 源文件、.h 文件中的任何一个比目标.o 文件“更新”(在上一次 make 之后被修改)。则根据规则重新编译生成它;

 第三: 目标.o 文件存在,目标.o 文件比它的任何一个依赖文件(的.c 源文件、.h 文件) “更新”(它的依赖文件在上一次 make 之后没有被修改),则什么也不做。 这些.o 文件所在的规则之所以会被执行,是因为这些.o 文件出现在“默认目标” 的依赖列表中。在 Makefile 中一个规则的目标如果不是“默认目标”所依赖的(或者 “终极目标”的依赖文件所依赖的),那么这个规则将不会被执行,除非明确指定执行这个规则(可以通过 make 的命令行指定重建目标,那么这个目标所在的规则就会被执行,例如 “make clean”)。在编译或者重新编译生成一个.o 文件时,make 同样会去 寻找它的依赖文件的重建规则(是这样一个规则:这个依赖文件在规则中作为目标出现),在这里就是.c 和.h 文件的重建规则。

你可能感兴趣的:(Makefile,开发语言,汇编)