make 大矣深矣。
这里首先向贝尔实验室的Feldman博士致敬, 是他创造了解放了程序员生产力的make工具。
言归正传,这里接着我们昨天的假设,已经有了一个项目,包含了三个.c文件和一个.h文件:
test.c initapi.c randapi.c ramdapi.h。
手工编译的话,只需要一下一条命令就可以完成
gcc -o test test.c initapi.c randapi.c
对于有数百上千的大项目,这样手工编译的方法就老费劲了,Feldman博士是怎样想到要自动化手工操作的呢?
带着这个问题,我们先吧刚才的手工过程分解了:
gcc -c -o test.o test.c
gcc -c -o initapi.o initapi.c
gcc -c -o randapi.o randapi.c
gcc -o test test.o randapi.o initapi.o
很明显,上述编译命令应当放到脚本中,以下显示了build脚本的内容:
#!/bin/sh
gcc -c -o test.o test.c
gcc -c -o initapi.o initapi.c
gcc -c -o randapi.o randapi.c
gcc -o test test.o randapi.o initapi.o
以上可以称之为“外壳脚本”,对于小项目还能凑合着用,但随着文件的增加,一次又一次的重复生成整个项目将成为程序员的鸡肋,Feldman博士开始了其思考:制造一个叫做make的工具来“理解”项目中的依赖关系。也就是进一步的抽象化build脚本。
使用Makefile作为默认文件名来知道make工具如何生成项目。
-------------------Makefile v1---------------------------------
RM = rm -f
test:test.o initapi.o randapi.o
gcc -o test test.o randapi.o initapi.o
test.o:test.c randapi.h
gcc -c -o test.o test.c
initapi.o: initapi.c randapi.h
gcc -c -o initapi.o initapi.c
randapi.o: randapi.c randapi.h
gcc -c -o randapi.o randapi.c
clean:
$(RM) *.o
运行一把,好像和先前的build 脚本表象行为一样, 优势在哪里呢?
这需要理解makefile依赖的表达树,能够对文件设定的依赖关系进行增量版本的生成。makefile还有一个重要的优势就是其变量
-------------------Makefile v2---------------------------------
RM = rm -f
MY_VAR = you call me
test:test.o initapi.o randapi.o
gcc -o test test.o randapi.o initapi.o
test.o:test.c randapi.h
gcc -c -o test.o test.c
initapi.o: initapi.c randapi.h
gcc -c -o initapi.o initapi.c
randapi.o: randapi.c randapi.h
gcc -c -o randapi.o randapi.c
clean:
$(RM) *.o
all:
echo ${MY_VAR}
如这个版本的Makefile里,增加了两个Makefile变量
MY_VAR和RM
makefile中变量的一个常见应用是保存和操纵make过程中需要用到的文件名和路径.
--------------------------Makefile v3---------------------------------
SRC_VAR= My test string for makefile.
TEST1_VAR=$(subset for, foo, ${SRC_VAR})
TEST2_VAR=$(patsubset t%t, T%T, ${SRC_VAR})
TEST3_VAR=$(filter %ing %able, $(SRC_VAR))
TEST4_VAR=$(sort ${SRC_VAR})
TEST5_VAR=$(words ${SRC_VAR})
TEST6_VAR=$(word 2 ${SRC_VAR})
TEST7_VAR=$(wordlist 2, 3, ${SRC_VAR})
all:
@echo original str:${SRC_VAR})
@echo substitution:${TEST1_VAR})
@echo pattern sub:${TEST2_VAR})
@echo filter str:${TEST3_VAR})
@echo sort str:${TEST4_VAR})
@echo word count:${TEST5_VAR})
@echo word 2:${TEST6_VAR})
@echo word2 thru 4:${TEST7_VAR}
makefile 中参数最主要的用途是保存和操纵与生成过程有关的文件名和地址信息。
将一种类型的文件转化为另一种类型的文件常常要求遵循特定的模式,而不需要对应特定的文件。
即“类型规则”.