公平警告:我在使用 makefile 方面有点新手,所以这可能是显而易见的。我要做的是使用 make 来运行第三方代码生成工具,当且仅当该生成工具的源文件(称为 .abc 文件)发生更改时。我在http://www.cmcrossroads.com/ask-mr-make/6795-rebuilding-when-a-files-checksum-changes引用了这个例子,它展示了如何构建 MD5,我稍微调整了这个想法:
文件:abc.mk
target = all
files := $(wildcard Abc/*.abc)
bltfiles := $files $(addsuffix .built,$files)
all: $bltfiles
%.built: %.abc %.abc.md5
@echo "Building $*"
@ #Command that generates code from a .abc file
@touch $@
%.md5: FORCE
@echo "Checking $* for changes..."
@ #Command to update the .md5 file, if the sum of the .abc file is different
FORCE:
我打算让每个 .abc 文件有两个辅助文件: .abc.built & .abc.md5 。.built 文件只是最后一次构建的虚拟目标和时间戳,因为生成工具生成的代码不能轻易定义为目标。.md5 文件包含 .abc 文件最后已知内容的哈希值。仅当文件的哈希更改时才应更新它。
但是,.built 文件仅在不存在时才会创建。.md5 规则根本不会运行,即使 .abc 文件具有较新的时间戳,.built 规则也不会重新构建。难道我做错了什么?
更新: 为了后代,这是我要工作的版本:
文件:abc.mk
# Call this makefile as: make all --file=abc.mk
# Default Target
target = all
COMP_ABC_FILES := $(wildcard Abc/*.abc)
COMP_BLT_FILES := $(COMP_ABC_FILES) $(addsuffix .built, $(COMP_ABC_FILES) )
# This line is needed to keep make from deleting intermediary output files:
.SECONDARY:
# Targets:
.PHONY: all
all: $(COMP_BLT_FILES)
Abc/%.abc.built: Abc/%.abc Abc/%.abc.md5
@echo "Building $*"
@ #Command that generates code from a .abc file
@touch $@
%.md5: FORCE
@echo "Checking $* for changes..."
@$(if $(filter-out $(shell cat $@ 2>/dev/null),$(shell md5sum $*)),md5sum $* > $@)
# Empty rule to force re-build of files:
FORCE:
clean:
@echo "Cleaning .built & .md5 files..."
@rm Abc/*.built
@rm Abc/*.md5