背景
最近在看ATF代码的时候,想要编译下,实施起来遇到一些问题,其中makefile有些命令,语法不是很清晰,故希望重新系统学习下。学习主要参考跟我一起写Makefile-陈皓.pdf。
第一部分、概述
makefile解决的问题:实现高效(控制文件是否编译,以及编译先后顺序等),自动化编译。
makefile的本质核心:文件依赖性
第二部分、关于程序的编译和链接
略
第三部分、 Makefile 介绍
核心思想:
1)如果这个工程没有编译过,那么我们的所有 C 文件都要编译并被链接。
2)如果这个工程的某几个 C 文件被修改,那么我们只编译被修改的 C 文件,并链接目
标程。
3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的 C 文件,
并链接目标程序。
一、 Makefile 的规则
target ... : prerequisites ...
command
...
...
target:规则的目标;可以是目标文件,可以是执行文件,也可以是个标签
prerequisites:生成target所需要的文件或目标
command:规则的命令行;是make程序所有的执行动作;一个规则可以有多个命令行,每一条命令占一行;注意:每一个命令行必须以[Tab]字符开始,[Tab]字符告诉 make 此行是一个命令行。 make 按照命令完成相应的动作。这也是书写Makefile 中容易产生,而且比较隐蔽的错误。
总结:target依赖于prerequisites的文件,其生成规则在command中进行定义
二、 Makefile 是如何工作的
通常情况下,在命令窗口中输入make命令:
1、make 会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2、如果找到,它会找文件中的第一个目标文件(target)并把这个文件作为最终的目标文件,然后基于规则进行生成;如果没找到,则停止并提示"make: *** No targets. Stop."
三、makefile 中使用变量
#定义变量objects
objects := main.o kbd.o command.o display.o
#变量引用
$(objects)
四、makefile 自动推导
只要 make 看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果 make找到一个 whatever.o,那么 whatever.c,就会是 whatever.o 的依赖文件。故目标文件的依赖在makefile中不必显式的列出。上述是makefile的“隐晦规则”
五、清空目标文件的规则
不要放在文件的开头,否则其会变成 make 的默认目标
第四部分、 Makefile 总述
一、makefile里有什么?
1、显式规则
书写者,明确指出目标文件,依赖项,生成的命令。
2、隐晦规则
书写者利用make的自动推导功能,进行简化撰写
3、变量定义
类似C语言中的宏定义,当 Makefile 被执行时,其中的变量都会被扩展到相应的引用位置上。
4、文件指示
1>Makefile 中引用另一个 Makefile,就像 C 语言中的include 一样
2>根据某些情况指定 Makefile 中的有效部分,就像 C 语言中的预编译#if 一样
3>定义一个多行的命令(后续补充)
5、注释
其注释是用“#”字符,如果你要在你的 Makefile 中使用“#”字符,可以用反斜框进行转义,如:“\#”
二、 Makefile 的文件名
三、 引用其它的 Makefile
语法include <filename>
其功能类似于C语言中的#include
include 前面可以有空字符,但不能是[Tab]键开始;include 和<filename>可以用一个或多个空格隔开
四、make 的工作方式
第五部分、书写规则
规则包含两个部分:依赖关系和生成目标的方法。
Makefile 中应该只有一个最终目标,其它的目标都是被这个目标所连带出来的。
目录由“冒号”分隔
为了显式的指出目标仅仅是个标签而不是个文件,故通过一个特殊的标记“.PHONY”来显
示地指明
自动化变量:基于下面的代码进行描述“$<”表示所有的依赖目标集(也就是“foo.c bar.c”), “$@”表示目标集(也就是“foo.o bar.o”)
objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@