以下总结来自:
yshell与Makefile区别及总结_bewinged的博客-CSDN博客_shell与makefile
其中第7点较难理解。经过尝试我将补充其解释
Makefile与shell脚本区别
http://blog.csdn.net/absurd/article/details/636418
1.通配符不一样
shell:*
Makefile:%
2.引用变量不一样
shell:$var 或者${var}
Makefile:$(var)
3.Makefile的target里面才执行shell脚本或者用函数$(shell pwd),其他地方不会
4.Makefile的每一行都是开辟一个进程来执行,所有要执行多个shell用\,来认为一行,所以多行设定变量时,里面无法传递变量,见下面例子
5.变量赋值
shell:不允许有空格
Makefile:允许有空格
6.特殊情况
Makefile为了避免和shell的变量冲突,shell的变量以$$开头
PROJECT_ROOT_DIR = $(shell pwd | awk -F'/application|/base_class' '{print $$1}')
7.make在调用Shell之前先进行预处理,即展开所有Makefile的变量和函数
shell自己的变量$$GOOD_DIR
Makefile的变量$(GOOD_DIR)
cat Makefile
GOOD_DIR="you are"
all:
@GOOD_DIR=arm-linux;\
echo $$GOOD_DIR; echo $(GOOD_DIR)
@echo $(GOOD_DIR)
zengzhihao@yingyongbu:~/work_place/test/youtest$ make
arm-linux
you are
you are
zengzhihao@yingyongbu:~/work_place/test/youtest$ make GOOD_DIR=outside
arm-linux
outside
outside
条件判断if
shell:
if [ $NOW_VAR == 1 ];then
echo "var is 1"
elif [ $NOW_VAR == 2 ];then
echo "var is 2"
else
echo "var is not 1"
fi
Makefile:
NOW_DIR=$(shell pwd)
ifeq ($(NOW_VAR), 1)
NOW_DIR="in 1"
else ifeq ($(NOW_VAR), 2)
NOW_DIR="in 2"
else
NOW_DIR="in not 1 or 2"
endif
all:
echo $(NOW_DIR)
ifneq ($(NOW_VAR), 1)
endif
ifdef V
endif
ifndef V
endif
for循环
shell:
for pid in ${pids};
do
xxxxx
done
while循环
shell:
while true
do
xxxx
done
Makefile中的for循环,采用shell的for循环
file=1 2 3 4 5
all:
for name in $(file); \
do \
echo $$name; \
done
例子
两种实现方式
all:
CC=arm-linux;echo $$CC
all:
@CC=arm-linux;\
echo $$CC
注意:
- \后紧跟回车,将多行当作1行。因为第4条,makefile的每一行都是开辟一个进程来执行,不能传递变量。
- makefile在输入到shell之前会完成预处理,会将变量代换
可见,shell变量$$被替换为$(与字符串中的转义转义符类似),这在执行的时候会输出新赋值的arm-linux;
makefile变量被替换为makefile中为变量定义的值,这步操作在all内的执行变量赋值前(也就是GOOD_DIR=you are)
在make后为GOOD_DIR赋新值,在替换时使用的就是新值 I am
需要注意的是,makefile中的GOOD_DIR和shell中的GOOD_DIR始终是一个变量, 造成他们表现不同的原因是makefile变量$和shell变量$$被替换时间不同