Linux Makefile与Shell的题目
大约只有晓得Makefile的人,都晓得Makefile可以调用Shell脚本。但是在现实运用时,并不那么简略,一些模棱两可的地方可能会让你抓狂。你若不信,可以先看几个例子,想象一下这些这些例子会打印什么内容,记下你想象的效果,然后在盘算机上运转这些例子,对比看一下。
示例一:
if [ "$(BUILD)" = "debug" ]; then echo "build debug"; else echo "build release"; fi
all:
echo "done"
示例二:
all:
@CC=arm-linux-gcc
@echo $(CC)
示例三:
CC=arm-linux-gcc
all:
@echo $(CC)
示例四:
SUBDIR=src example
all:
@for subdir in $(SUBDIR); \
do\
echo "building " $(subdir); \
done
注明:
1. Shell脚本在target里才有效,其它地方都被忽略掉了。所以示例一中,”build debug”之类的字符串基本打印不出来。示例一的准确写法是:
示例一:
all:
if [ "$(BUILD)" = "debug" ]; then echo "build debug"; else echo "build release"; fi
echo "done"
2. make把每一行Shell脚本当作一个独立的单元,它们在独自的进程中运转。示例二中,两行Shell脚本在两个莫不相关的进程里运转,第一个进程把CC设置为arm-linux-gcc,第二个进程是不晓得的,所以打印的效果天然不是arm-linux-gcc了。示例二的准确写法是:
示例二:
all:
@CC=arm-linux-gcc; echo $(CC)
或者:
all:
@CC=arm-linux-gcc; \
echo $(CC)
3. make在调用Shell以前先进行预处置,即展开所有Makefile的变量和函数。这些变量和函数都以$开头。示例三中,Shell拿的脚本现实上是echo arm-linux-gcc,所以打印效果准确。
4. make预处置时,所有以$开头的,它都不会放过。要想援用Shell本人的变量,应当以$$开头。另外要注意,Shell本人的变量是不需要括号的。示例四的准确写法是:
示例四:
SUBDIR=src example
all:
@for subdir in $(SUBDIR); \
do\
echo "building " $$subdir; \
done