LINUX学习之初识Makefile(一)
Makefile基础知识
什么是Makefile
Makefile就是一个文件,其中定义了很多规则,描述哪些文件需要先编译、哪些后编译,哪些需要重新编译,通过make工具即可完成整个工程的编译及链接
Makefile基本规则
首先通过一串代码来引入Makefile的基本规则:
1 main: main.o input.o calcu.o
2 gcc -o main main.o input.o calcu.o
3 main.o: main.c
4 gcc -c main.c
5 input.o: input.c
6 gcc -c input.c
7 calcu.o: calcu.c
8 gcc -c calcu.c
9
10 clean:
11 rm *.o
12 rm main
由上面的代码可以观察到Makefile的基本规则为:
目标:依赖
(tab)规则
尤其需要注意的是规则必须以tab开头!
目标:目标也分为一般目标和伪目标,一般目标指我们需要的最终文件,即make以后得输出文件。伪目标是一种特殊得目标,只是一个标签,不会被当成文件看待。
伪目标的格式:.PHONY : xxx 例如.PHONY:clean
依赖:生成该目标所需的一些文件
规则:由依赖文件生成目标文件的手段,用来描述在什么情况下使用什么命令来构建一个特定的文件,这个文件就是规则的“目标” ,为了生成这个“目标”而作为材料的其它文件称为“目标”的依赖,规则的命令是用来创建或者更新目标的
main.o: main.c //在此处,main.o就是要生成的目标,main.c就是依赖
gcc -c main.c // 此行即由依赖生成目标不编译main.c生成main.o
Make执行过程:
1、make 命令会在当前目录下查找 Makefile命名的文件。
2、 当找到 Makefile 文件以后就会按照 Makefile中定义的规则去编译生成最终的目标文件。
3、当发现目标文件不存在,或者目标所依赖的文件比目标文件新(也就是最后修改时间比目标文件晚)的话就会执行后面的命令来更新目标。
Makefile变量
变量的引入:
1 #Makefile 变量的使用
2 objects = main.o input.o calcu.o //objects 即为变量,并通过 = 赋值符把main.o input.o calcu.o 字符串赋给objects变量
3 main: $(objects) //变量的引用方法是“$(变量名)”
4 gcc -o main $(objects)
变量赋值符:
- “=” 赋值符
使用 “=” 在给变量的赋值的时候, 不一定要用已经定义好的值, 也可以使用后面定义的值。
name = abc
realname = $(abc)
name = ABC
print:
@echo realname:$(name)
以上代码段最后输出结果为realname:ABC ,变量的真实值取决于它所引用的变量的最后一次有效值
- "?="赋值符
realname ?= ABC
如果变量 realname 前面没有被赋值, 那么此变量就是 “ABC” ,如果前面已经赋过值了,那么就使用前面赋的值
- ":="赋值符
name = abc
realname := $(abc)
name = ABC
print:
@echo realname:$(name)
以上代码段输出结果为 realname = abc ,赋值符 “:=” 不会使用后面定义的变量,只能使用前面已经定义好的
- ”+=“变量追加赋值符
object : main.o input.o
object += calcu.o
第一行变量object的值为 main.o input.o ,第二行追加了一个calcu.o,object变量的值就为main.o input.o calcu.o三个值。
- Makefile自动化变量
自动化变量就是这种变量会把模式中所定义的一系列的文件自动的挨个取出,直至所有的符合模式的文件都取完,自动化变量只应该出现在规则的命令中。
常用的自动化变量有如下几种:
$@ :规则中的目标
$< :规则中的第一个依赖条件
$^ :规则中的所有依赖条件
例如:
finally: main.c calcu.c input.c
gcc $^ - o $@
$^即为main.c,calcu.c,input.c,这三个为规则中的所有依赖文件
$@即为finally ,为规则中的目标
1 objects = main.o input.o calcu.o
2 main: $(objects)
3 gcc -o main $(objects)
4
5 main.o : main.c
6 gcc -c $<
7
8 clean:
9 rm *.o
10 rm main
$<为规则中第一个依赖条件,即main.c
模式规则
通过模式规则我们就可以使用一条规则来将所有的.c 文件编译为对应的.o 文件,目标中的 “%”表示对文件名的匹配, “%”表示长度任意的非空字符串,比如“%.c”就是所有的以.c 结尾的文件。
/*使用方法*/
%.o : %.c
命令
因此,文章开头的代码也可以改为如下形式:
1 objects = main.o input.o calcu.o
2 main: $(objects)
3 gcc -o main $(objects)
4
5 %.o : %.c
6 gcc -c $<
7
8 clean:
9 rm *.o
10 rm main
即main.o ,input.o,calcu.o由main.c,input.c,calcu.c生成