@echo 开始编译: 表示在make执行的时候不会回显这个将要被执行的命令,相当于批处理的echo off
如果命令之前没有@,echo 开始编译除了会输出具体make命令的执行结果,还会输出被执行的命令,因此得到
“echo 开始编译
开始编译”
make 参数“-s"或者”--slient"禁止所有执行命令的显示,等同于所有的命令行均使用了@
-n或者--just-print,则值显示所有要执行的命令,不会真正去执行这些命令。只有在这种情况下make才会打印出所有make需要执行的命令,包括使用了@的命令
2 关于命令执行的错误:
如果make中某些命令错误了但你想继续执行下面的命令,可以在tab之后命令之前加上-符号。
clean:
-rm *.o
其含义是:即使执行“rm”删除文件失败,make也继续执行。
在执行make时,如果使用命令行选项“-i”或者“—ignore-errors”, make将忽略所有规则中命令执行的错误。
当使用make的“-i”选项或者使用“-”字符来忽略命令执行的错误时,make始终把命令的执行结果作为成功来对待。但会提示错误信息,同时提示这个错误被忽略
Tip:在make执行失败时,修改错误之后执行make之前,使用“make clean”明确的删除第一次错误重建的所有目标。
3make并发执行:
可以通过make的命令行选项“-j”或者“--job”来告诉make在同一时刻可以允许多条命令同时被执行(注意,在MS-DOS中此选项无效,因为它是单任务操作系统)。
如果选项“-j”之后存在一个整数,其含义是告诉make在同一时刻可允许同时执行命令的数目。这个数字被称为“job slots”。当“-j”选项之后没有出现一个数字时,那么同一时刻执行的命令数目没有要求。使用默认的“job slots”,值为1。
3MAKE变量:
1 递归展开式变量:这一类型变量的定义是通过“=”或者使用指示符“define”定义的。在引用的地方严格文本替换,如果变量中存在对其他变量的引用则会同时被展开。
foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:;echo $(foo)
执行“make”将会打印出“Huh?”
特点: 可以先引用后定义
CFLAGS = $(include_dirs) -O
include_dirs = -Ifoo -Ibar
“CFLAGS”会在命令中被展开为“-Ifoo -Ibar -O”。而在“CFLAGS”的定义中使用了其后才定义的变量“include_dirs”。
容易产生无限递归CFLAGS = $(CFLAGS) –O
2 直接扩展式变量:
这种风格的变量使用“:=”定义。在使用“:=”定义变量时,变量值中对其他量或者函数的引用在定义变量时被展开(对变量进行替换)。所以变量被定义后就是一个实际需要的文本串,其中不再包含任何变量的引用。
不能先引用后定义
?=操作符:
只有此变量在之前没有赋值的情况下才会对这个变量进行赋值。例如:
FOO ?= bar
其等价于:
ifeq ($(origin FOO), undefined)
FOO = bar
endif
含义是:如果变量“FOO”在之前没有定义,就给它赋值“bar”。否则不改变它的值。
变量的替换引用:
格式为“$(VAR:A=B)”(或者“${VAR:A=B}”),意思是,替换变量“VAR”中所有“A”字符结尾的字为“B”结尾的字。如foo := a.o b.o c.o
bar := $(foo:.o=.c)
override指示符:
在执行make时,如果通过命令行定义了一个变量将替代Makefile中出现的同名变量。如果不希望命令行指定的变量值替代在Makefile中的变量定义,则需要什么override
override VARIABLE = VALUE
或者:
override VARIABLE := VALUE
也可以对变量使用追加方式:
override VARIABLE += MORE TEXT
举个例子说明下:
如果makefile是这个样子的
EXEF=FOO
override CFLAGS+=-Wall -g
foo:foo.c
echo "CFLAGS=$(CFLAGS)"
[root@v52540394719 make]# make
echo "CFLAGS=-Wall -g"
CFLAGS=-Wall -g
[root@v52540394719 make]# make CFLAGS=-O2
echo "CFLAGS=-O2 -Wall -g"
CFLAGS=-O2 -Wall -g
看出两者的不同了吗?
我觉得这个override不能按照字面理解,实际是不能override
4 make使用系统环境变量
使用环境变量需要注意以下几点:
1. 在Makefile中对一个变量的定义或者以make命令行形式对一个变量的定义,都将覆盖同名的环境变量(注意:它并不改变系统环境变量定义,被修改的环境变量只在make执行过程有效)。而make使用“-e”参数时,Makefile和命令行定义的变量不会覆盖同名的环境变量,make将使用系统环境变量中这些变量的定义值。
2. make的递归调用中,所有的系统环境变量会被传递给下一级make。默认情况下,只有环境变量和通过命令行方式定义的变量才会被传递给子make进程。在Makefile中定义的普通变量需要传递给子make时需要使用“export”指示符来对它声明。
3. 一个比较特殊的是环将变量“SHELL”。在系统中这个环境变量的用途是用来指定用户和系统的交互接口,显然对于make是不合适的。因此make的执行环境变量“SHELL”没有使用同名的环境变量定义,而是“/bin/sh”。make默认“/bin/sh”作为它的命令行解释程序(make在执行之前将变量“SHELL”设置为“/bin/sh”)