代码变成可执行文件,叫做
编译;编译的安排(编译的顺序)叫做
构建(build)。
make是一种构建工具,主要用于C语言的构建。但是实际上,只要某个文件有变化,就要重新构建的项目,都可以用Make构建。
一、Make概念
make是一个根据指定的Shell命令进行构建的工具。它的规则很简单,你规定要构建哪个文件,它依赖哪些源文件,当那些文件有变动时,如何构建它。
构建规则都写在一个叫做Makefile的文件中,Make命令依赖这个文件进行构建。Makefile文件也可以写为makefile, 或者用命令行参数指定为其他文件名。
$ make -f rules.txt
# 或者
$ make --file=rules.txt
二、Makefile文件的格式
Makefile文件由一系列规则(rules)构成。每条规则的形式如下:
<target> : <prerequisites>
[tab] <commands>
第一行为
目标:
前置条件;第二行为tab键,后面跟着
命令。
目标是必须的,前置条件和命令可选,两者必须存在一个。
每条规则说明了:构建目标的前置条件是什么,以及如何构建。
$ make
上述命令执行Makefile文件的第一个目标。
(1)
目标通常是文件名,指明Make所需要构建的对象;目标可以是一个文件名,也可以是多个文件名,中间用空格分隔。如下:
source: file1 file2 file3
除了文件名,
目标还可以是某个操作的名字,这称为"伪目标"(phony target)。如下:
clean:
rm *.o
$ make clean
上述命令执行clean目标。如果当前目录中存在一个clean文件,那么将不会构建,因为Make发现clean文件以及存在了,就不需要构建了。
如果要避免这种情况,需要声明clean目标为“伪目标”,写法如下:
.PHONY: clean
clean:
rm *.o temp
这样,Make不会检查make文件,每次运行都会执行。
(2)前置条件指明了
“目标”是否重新构建的判断标准,只要一个前置文件不存在或者有过更新,“目标”就要重新构建。
source.txt:
echo "this is the source" > source.txt
如果没有前置条件:source.txt后面没有前置条件,就意味着它跟其他文件都无关,只要这个文件还不存在,每次调用make source.txt,它都会生成。
(3)命令表明如何更新目标文件。由
一行或者
多行(不是多个!所以是不同行!)Shell命令组成。命令之前必须有一个tab键。如果想用其他键,可以用内置变量.RECIPEPREFIX声明。如下:
.RECIPEPREFIX = >
all:
> echo Hello, world
上面代码用>替代tab键。
每个命令在一个单独的shell中执行,这些
shell无继承关系。如:
var-lost:
export foo=bar
echo "foo=[$$foo]"
执行make var-lost,取不到foo的值。因为两行命令在不同的进程执行。
如果要取到foo的值,需要把
两个命令写在一行,中间用分号隔开。
export foo=bar; echo "foo=[$$foo]"
还有一种解决方案,在
换行符前加反斜杠转义。
export foo=bar;
\ echo "foo=[$$foo]"
最后一个方法是
加上.ONESHELL命令。
.ONESHELL:
var-kept:
export foo=bar;
echo "foo=[$$foo]"
(4)注释
用#注释。
正常情况下,make会打印每条命令,然后再执行,这就叫做回声(echoing)。
在命令前面加@,关闭回声。