makefile中常见的一些问题和需要注意的地方
强制执行
每一条命令运行完,make会检查返回码,如果成功执行,会执行下一条命令,所有命令都正确执行,这个规则就算是执行成功。如果其中有一条命令执行失败,make就会终止当前规则,导致终止所有规则的执行。
个别时候,命令出错不一定是错的,比如mkdir,如果目录存在,那就不需要我们创建了,我们并不会觉得这是一个错误,我们希望程序继续执行。我们需要忽略这个错误。可以在命令前加-
如:
clean: |
回显问题
make会先在shell打印我们的命令,然后才会执行,我们如果不想让它打印我们的命令,需要在前面加上@
all: |
命令包和eval
eval的作用是把一段文本当作makefile内容$(eval $(text))
define var = |
与之类似的出现过的概念叫命令包,就是定义一个多行变量,变量里的内容是一些命令。
define var = |
注意:需要区分这两者,一个是把文本当makefile里的内容,一个只是把文本当作一堆命令,并不能解析为目标依赖。
命令执行调用shell
make在执行命令的时候是调用/bin/sh来执行的,每一行命令都会调用一个shell来执行。
这样你在shell里定义的变量就无法被其他shell使用,如果我们想让多个命令在同一个shell里运行,就需要把它们写在同一行上,然后使用分号隔开。
|
后缀替换
在makefile里有多种替换后缀的方式,我们在这里对他们进行区分
模式替换
这是变量的特性
语法:$(var:a=b)
,意思是将变量var的值当中每一项结尾的a替换为b,直接上例子。
files = main.cpp hello.cpp |
subst
这是全局替换,会替换每一个匹配到的字符串
var1 = demo1.c demo2.c demo3.c |
patsubst
这是模式替换,作用和变量的模式替换一样,都可以做到对后缀的替换。
var1 = demo1.c demo2.c demo3.c |
MAKEFILES
一个特殊的环境变量,可能会影响正常执行。详情见陈浩老师的《跟我一起写Makefile》