1、概述
此系列是为自己做的一个总结,不是很系统,主要目的是记录linux下我认为经常忘的方方面面。
2、makefile的规则
target: prerequisites
command
...
...
target也就是一个目标文件,可以是Object File,也可以是执行文件。
prerequisites就是,要生成那个target所需要的文件或是目标,也就是依赖项。
command也就是make需要执行的命令。(任意的Shell命令)
在Makefile中的命令,必须要以[Tab]键开始。
这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。
举个栗子:最简单的hello world程序:只有一个文件main.c,那么我们如何写makefile来生成可执行文件呢?
(1)、首先我们需要把main.c编译为中间文件。
(2)、有了中间文件,我们就可以通过连接来得到最终的可执行文件了。
那么思路理清楚了,看下makefile的写法:
test : main.o
gcc -o test main.o
main.o : main.c
gcc -c main.c
clean :
rm main.o test
解释一下:第一行 test : main.o 声明了最后要得到的可执行文件名为test,他依赖于main.o,连接的命令为:gcc -o test main.o
明白了第一、二行以下的就不用多说了。
3、makefile原理
我们编译的时候一般情况下只执行make就可以了,那么这个命令到底是如何一层层的为我们编译出可执行文件的?步奏如下:
1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“test”这个文件,并把这个文件作为最终的目标文件。
3、如果test文件不存在,或者test所依赖的后面的 main.o 文件的文件修改时间要比test这个文件新,那么,他就会执行后面所定义的命令:gcc
-o test main.o来生成test这个文件。
4、如果test所依赖的main.o文件也不存在,那么make会在当前文件中找目标为main.o文件的依赖性main.c, 如果找到则再根据那一个规则:gcc
-c main.c生成main.o文件。
5、当然,如果你的main.c文件不存在,make会报错,如果存在则会生成main.o然后再生成test。
整个过程就像是堆栈一样,一层层的往下。
4、让makefile使用变量
在上述makefile中,main.o出现了三次,示例的文件很少这没什么问题,如果有10个中间文件呢? 100个呢? 我们要重复写三遍? 然后中间文件变化了,要在三个地方去改动? 这明显很不容易维护,这种情况我们可以使用变量(理解为宏更好理解一些,就是替换而已)。
变量语法:<name> = <..> <...>
使用的时候:$(<name>)就可以了。
那么上述makefile变为:
obj = main.o
test : $(obj)
gcc -o test $(obj)
main.o : main.c
gcc -c main.c
clean :
rm
$(obj) test
这样一来如果我们的中间文件发生变化,就很容易了只需要改动obj = main.o就可以了。
5、让make自己推导
在第三章节中,整个程序也就几行,可是makefile却这么繁琐,难道不能简化了么?答案是可以的。
(1):自动make自动推导命令:
test : main.o
在make中他会自动推导出下面的命令gcc -o test main.o,于是上面的makefile可以变化为:
test : main.o
main.o : main.c
clean :
rm main.o test
还能简化么? 能!
make会自动推导依赖关系,如果没有显示的写出main.o的依赖关系,make会自动推导出main.o依赖于main.c。那么上面的makefile就变成了这样:
test : main.o
clean :
rm main.o test
现在简单了吧。
6、clean规则
在makefile中虽然clean不是必须的,但是为了我们重新编译,我们需要一个清理中间文件和结果文件的命令,clean不要放在makefile的最开始,不然当你执行make的时候会默认执行clean这不是我们想要的,一般来说clean都放在整个makefile的结尾处。
版权声明:本文为博主原创文章,未经博主允许不得转载。