1.什么是Makefile,为什么要学习Makefile?
Makefile 文件描述了整个工程的编译、连接等规则。其中包括:工程中的哪些源文件需要编译以及如何编译、需要创建那些库文件以及如何创建这些库文件、如何最后产生我们想要得可执行文件。尽管看起来可能是很复杂的事情,但是为工程编写 Makefile 的好处是能够使用一行命令来完成“自动化编译”,一旦提供一个(通常对于一个工程来说会是多个)正确的 Makefile。编译整个工程你所要做的唯一的一件事就是在 shell 提示符下输入 make 命令。整个工程完全自动编译,极大提高了效率。
也就是说,掌握了Makefile的编写,就能让我们在Linux下的项目编译效率得到极大的提高,只需要执行一个make命令即可。而不需要我们一条一条gcc g++ 命令慢慢的敲。
2.在了解makefile之前,先了解下面几个概念:
a.静态库:又称为文档文件(Archive File)。它是多个.o 文件(编译生成的目标文件)的集合。Linux 中静态库文件的后缀为“.a”。静态库中的各个成员(.o 文件)没有特殊的存在格式,仅仅是一个.o 文件的集合。使用“ar”工具维护和管理静态库。
b.共享库:也是多个.o 文件的集合,但是这些.o 文件时有编译器按照一种特殊的方式生成(Linux ***享库文件格式通常为“ELF”格式。共享库已经具备了可执行条件)。模块中各个成员的地址(变量引用和函数调用)都是相对地址。使用此共享库的程序在运行时,共享库被动态加载到内存并和主程序在内存中进行连接。多个可执行程序可共享库文件的代码段(多个程序可以共享的使用库中的某一个模块,共享代码,不共享数据)。另外共享库的成员对象可被执行(由 libdl.so 提供支持)。
3.make命令
make命令根据Makefile中定义的编译,链接规则来编译源代码和链接程序。
make 通过比较对应文件(规则的目标和依赖,)的最后修改时间,来决定哪些文
件需要更新、那些文件不需要更新。对需要更新的文件 make 就执行数据库中所记录的
相应命令(在 make 读取 Makefile 以后会建立一个编译过程的描述数据库。此数据库
中记录了所有各个文件之间的相互关系,以及它们的关系描述)来重建它,对于不需要
重建的文件 make 什么也不做。
4.哪些情况在执行make命令之后会被编译?
当使用make工具进行编译时,工程中以下几种文件在执行make时将会被编译(重新编译):
a. 所有的源文件没有被编译过,则对各个 C 源文件进行编译并进行链接,生成最后的可执行程序;源文件进行编译并进行链接,生成最后的可执行程序;
b. 每一个在上次执行 make 之后修改过的 C 源代码文件在本次执行 make 时将会被重新编译;
时将会被重新编译;
c. 头文件在上一次执行 make 之后被修改。则所有包含此头文件的 C 源文件在本次执行源文件在本次执行 make 时将会被重新编译。(慎重修改头文件,否则可能会使得重新编译非常耗时)
5.Makefile描述规则的基本语法
TARGET... : PREREQUISITES...
COMMAND
...
...
TARGET:规则的目标,就是我们这一条命令执行最终要得到什么结果,生成什么文件。可以是.o文件、也可以是最后的可执行程序的文件名等。另外,目标也可以是一个make执行的动作的名称,如目标“clean”,我们称这样的目标是“伪目标”。
PREREQUISITES:规则的依赖,生成规则目标所需要的文件名列表。通常一个目标依赖于一个或者多个文件。
command:规则的命令行。是规则所要执行的动作(任意的 shell 命令或者是可在shell 下执行的程序)。它限定了 make 执行这条规则时所需要的动作。
一个规则可以有多个命令行,每一条命令占一行。 注意:每一个命令行必须以[Tab]字符开始,[Tab] 字符告诉 make 此行是一个命令行。make 按照命令完成相应的动作。
[Tab]字符也是Makefile中常见而且隐蔽的错误。
一个目标可以没有依赖而只有动作(指定的命令)。比如 Makefile 中的目标“clean”,此目标没有
依赖,只有命令。