Makefile没有重建依赖项?

时间:2012-10-08 16:48:59

标签: linux makefile dependencies redhat

公平警告:我对使用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

2 个答案:

答案 0 :(得分:1)

将makefile修复到三个位置:

target = all
files    := $(wildcard Abc/*.abc)
bltfiles := $(files) $(patsubst %.abc,%.built,$(files))

all: $(bltfiles)

#Abc/%.abc.built: Abc/%.abc Abc/%.abc.md5
%.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:

请注意更改:

  1. bltfiles := $(files) $(patsubst %.abc,%.built,$(files))

    结果在“Abc / a.built Abc / b.built”而不是“Abc / a.abc.built Abc / b.abc.built”中,鉴于%.built的规则如何,这是必需的定义

  2. all: $(bltfiles)

    如上所述,对于$(files),'$ bltfiles'必须为$(bltfiles),否则make会将其解释为$(f)iles$(b)ltfiles

  3. 提示 :拥有一个带有makefile文件突出显示的编辑器很不错


    样本

    mkdir -pv Abc; touch Abc/{a,b,c,d,e,f,g}.abc
    make -Bs -f abc.mk
    

    输出

    Checking Abc/e.abc for changes...
    Building Abc/e
    Checking Abc/g.abc for changes...
    Building Abc/g
    Checking Abc/b.abc for changes...
    Building Abc/b
    Checking Abc/f.abc for changes...
    Building Abc/f
    Checking Abc/a.abc for changes...
    Building Abc/a
    Checking Abc/c.abc for changes...
    Building Abc/c
    Checking Abc/d.abc for changes...
    Building Abc/d
    

答案 1 :(得分:0)

如修正但未解释:Makefile语法与shell语法不同。默认情况下(由于丢失到历史记录的原因),变量只有一个字符长。如果需要更长的变量名,则必须将其放在括号中,以便正确解析。例如,编写$files实际上会扩展字符串“iles”,因为make会解析并仅扩展“f”变量的值(为空)。

是的,这很奇怪。但这是制作方式。始终将变量放在括号中。