Makefile学习笔记1
1. Makefile简介
gnu make(后面简称make)是一种自动化的构建工具,一般用于从源代码构建可执行程序。 make根据Makefile中编写的规则来处理构建过程中各种文件之间的依赖关系并自动执行构建过程。
2. Makefile的基本结构
在Makefile中,最主要的内容就是描述依赖关系以及构建命令,下面是一个最简单的Makefile。
hello_world : hello_world.c
gcc hello_world.c -o hello_word
将上面这个Makefile和hello_world.c
源代码放到同一目录中,并在该目录中执行make
命令就会得到hello_world
程序。在上面这个Makefile中,hello_word
是构建目标,hello_world.c
是构建hello_world
所需的依赖文件,gcc hello_world.c -o hello_word
是利用依赖生成目标的shell
命令, 所以,简单的Makefile的格式如下:
目标1 : 依赖文件1 依赖文件2 ...
生成目标的shell命令1
生成目标的shell命令2
...
目标2 : 依赖文件1 依赖文件2 ...
生成目标的shell命令1
生成目标的shell命令2
...
这里的每条shell命令前必须使用一个制表符(tab)来缩进,不缩进或者使用空格缩进都会导致错误。
当我们只执行make命令不指定目标参数时,make会尝试根据文件编写顺序找到第一个目标并调用目标的生成命令进行构建。如果该目标的某个依赖文件还不存在,make会在Makefile中搜索这个依赖文件的构建规则并先完成这个依赖文件的构建,再完成最终目标的构建。我们可以在调用make命令时指定构建目标,例如
make 目标2
这样make会构建我们指定的目标。
3. 使用变量
Makefile中可以使用变量,变量可以用于目标,依赖文件,shell命令等等位置,变量本身也可以为其他变量赋值,make在执行时会将这些变量替换成其保存的字符串。下面这个例子演示了Makefile的变量的基本使用方式:
program := hello_word
dependency := hello_world.c
$(program) : $(dpendency)
gcc $(dependency) -o $(program)
3.1 变量赋值
3.1.1 赋值符号赋值
# 方式一
program := hello_world
# 方式二
program = hello_world
# 方式三
program ?= hello_world
方式一为最普通的赋值方式,赋值符号为:=
,方式二为递归赋值方式,赋值符号为=
,方式三为条件赋值方式,赋值符号为?=
。
?=
赋值方式只有在被赋值的变量为空的情况下才会执行赋值操作,而:=
和=
会始终执行赋值操作。当右值(赋值符号右边的值)中没有变量时,使用:=
和=
进行赋值的结果是一致的;当右值中有变量时,:=
和=
进行变量展开的方式有所不同。:=
只对到当前行为止右值中的变量进行一次展开,所以各个变量的赋值顺序会影响赋值结果;而=
则会搜索整个Makefile后对变量进行展开,所以各个变量的赋值顺序不会影响赋值结果。下面是一个简单的例子:
1) 使用:=
赋值
x:=$(y)
y=$(z)
z=hello
all :
echo $(x)
z=haha
执行这个Make会输出
echo
即x的值为空,因为在第一行时变量y的值为空,变量y此时的值被直接赋给了x
2) 使用=
赋值
x=$(y)
y=$(z)
z=hello
all :
echo $(x)
z=haha
执行上面各种Makefile后会输出
echo haha
haha
即x的值为haha,x在使用时被递归展开,得到了变量z的最终值haha。
3.1.2 make命令赋值
make program=hello_world
在执行make命令时可以使用上述命令行参数来为变量赋值
3.2 变量的使用
为变量赋值时只需要使用变量名即可,而使用变量时需要将变量名放在$()
中,如果使用变量时变量没有放在$()
中,其会被当做一个普通的字符串。下面的例子使用了program和dependency变量。
$(program) : $(dpendency)
gcc $(dependency) -o $(program)
3.3 特殊变量
除了自定义的变量外,Makefile中还有一些特殊的变量,例如
hello_world : hello_world.c
gcc $@ -o $^
其中$@
表示所有依赖文件,在这里为hello_world.c
,$@
表示目标文件, 在这里为hello_word