甲. 让make 每次都执行特定的命令例子:all: date说明:all 是第一个目标,所以成为默认的目标.DEFAULT_GOAL由于all文件不存在,所以必须重新制作目标all,制作的方法是,执行date命令乙. 让make 每次都更新文件例子: 热热身.假如文件名是test.txt,每次执行make都更新test.txt最简单写法当然是:all: date test.txt但是, 为了增强功能,这里决定要使用宏, 例如把文件名用一个宏变量来表示.同时引入依赖, 这样更便于控制, 用以判断是否需要更新.file test.txt all: $(file) $(file) : date $分析: 上述写法,all依赖于$(file), 生成all的配方是空, 所以对all无需做任何事生成$(file)的配方是执行date 命令.如果$(file)已经存在, 则不必在执行配方命令.如果想让$(file)每次都更新,可以让它依赖于一个伪目标,如下示例file test.txt all: $(file) $(file) : FORCE date $ .PHONY FORCE说明:由于FORCE是不存在的,所以必须重新制作FORCE,但FORCE 是伪目标,所以总是可以制作成功.FORCE 更新了,所以要更新$(file), 其处方是date 命令, 所以$(file)被更新.丙. 让make 每次都判断,更新版本文件version.h例子: 来源于linux Makefile, 有自己的更改,我们考察一些其中的一些概念.当makefile 中三个变量改变的时候,就会更新version.h, version.h 就是这三个变量的变体.如果3个变量没有改变,则不必更新version.h,保留旧的时间戳.VERSION 2 PATCHLEVEL 3 SUBLEVEL 1 # filechk 用来检查产生的文件内容是否需要更新 # 使用: # $(call filechk,sample) # 实现: # 定义的版本好内容会输出到新文件 # 存在的文件会与新文件比较 # - 如果 旧文件不存在,使用新文件 # - 如果 旧文件和新文件内容不同,使用新文件 # - 如果 旧文件和新文件内容相同,使用旧文件,这样时间戳就不会改变. # $ 还是代表当前规则的目标 define filechk set -e; \ echo CHK $; \ mkdir -p $(dir $); \ $(create_$(1)) $.new; \ if [ -r $ ] cmp -s $ $.new; then \ rm -f $.new; \ else \ echo UPD $; \ mv -f $.new $; \ fi endef # 该函数向屏幕输出 版本信息, Makefile 直接调用 命令行函数完成创建. define create_version.h (echo \#define LINUX_VERSION_CODE $(shell expr $(VERSION) \* 65536 $(PATCHLEVEL) \* 256 $(SUBLEVEL)); \ echo #define KERNEL_VERSION(a,b,c) (((a) 16) ((b) 8) (c));) endef .PHONY: FORCE version.h: FORCE $(call filechk,version.h)说明,定义了2个函数,filechk, filechk_version.hfilechk_version.h 只是简单的向控制台输出两行 define 字符串. 可被重定向生成version.hfilechk 函数, 比较两个文件是否相同并决定是否替换文件.set -e 表示执行出错时立即退出调用了filechk_version.h 并把输出重定向到文件调用了cmp 程序,比较两个文件的内容,相同则保留旧的,不同则替换旧的.当你把主版本号, 或次版本号,build 号一改, 生成的文件与原文件不同,就替换原来的文件了.Makefile 中命令语句就是tab 开头的 shell 命令.Makefile 中定义的命令包又与纯bash_script 有区别, 例如$() 在bash中是执行命令而不是变量引用, ${}是变量引用, 无shell 命令, dir 与这里的dir 含义不同, 在这里写的命令包难以跟踪,难以调试, 最好别用!!!另一种写法,供参考VERSION 2 PATCHLEVEL 3 SUBLEVEL 1 VERSTR$(shell printf 0x%x $$((($(VERSION)16)($(PATCHLEVEL)8)$(SUBLEVEL)))) define filechk set -e; \ echo CHK $; \ $(filechk_$(1)) $.tmp; \ if [ -r $ ] cmp -s $ $.tmp; then \ rm -f $.tmp; \ else \ echo UPD $; \ mv -f $.tmp $; \ fi endef define filechk_version.h (echo #define KERNEL_VERSION(a,b,c) (a 16) (b 8) (c)); \ echo #define KERNEL_VERSION $(VERSTR); \ ) endef .PHONY: FORCE version.h: FORCE $(call filechk,version.h)