Makefile多个目标vs分离的目标为模式提供不同的结果

时间:2016-11-24 15:58:44

标签: makefile

我的makefile失败了。我的想法是从某个文件中提取文件并将它们放在一个临时目录中。然后将其rsync到源目录。由于rsync仅在文件更改时更新,因此除非必要,否则源目录中的makefile不会重新创建。我已经解决了以下问题:

.PHONY: extract clean

FILES = filea1.cc filea2.cc filea3.cc                       \
        filea1.hh filea2.hh filea3.hh                       \
        filea1.py filea2.py filea3.py                       \
        dir-cc/filea1.cc dir-cc/filea2.cc dir-cc/filea3.cc  \
        dir-cc/filea1.hh dir-cc/filea2.hh dir-cc/filea3.hh  \
        dir-py/filea1.py dir-py/filea2.py dir-py/filea3.py

PATTERN   := $(sort $(addprefix build/%., $(patsubst .%,%,$(suffix $(FILES)))))

extract: $(addprefix build/, $(FILES))

$(PATTERN):
    mkdir -p $(dir $@); echo "hello!" > $@

#build/%.cc:;mkdir -p $(dir $@); echo "hello!" > $@
#build/%.hh:;mkdir -p $(dir $@); echo "hello!" > $@
#build/%.py:;mkdir -p $(dir $@); echo "hello!" > $@

temp:
    echo $(PATTERN)

clean:
    rm -rf build

make make获得' build /%。cc build /%。hh build /%。py'但是'制作提取物'未能制作所有文件:

build:
dir-cc  dir-py  filea1.cc  filea2.cc  filea3.cc

build/dir-cc:
filea1.cc  filea2.cc  filea3.cc

build/dir-py:
filea1.py  filea2.py  filea3.py

hh文件丢失了。令人难以置信的是,在实际工作中,cc文件丢失了。无论如何,注释掉$(PATTERN),删除注释以便上面代码中的目标是分开的,确实得到了所有文件:

build:
dir-cc  filea1.cc  filea1.py  filea2.hh  filea3.cc  filea3.py
dir-py  filea1.hh  filea2.cc  filea2.py  filea3.hh

build/dir-cc:
filea1.cc  filea1.hh  filea2.cc  filea2.hh  filea3.cc  filea3.hh

build/dir-py:
filea1.py  filea2.py  filea3.py

由于在实际工作中一切都必须是自动的,并且所有目标的规则都是相同的(所以我不应该重新键入它),我非常喜欢第一个版本。我阅读了手册,但我很困惑为什么要这样做。我正在使用GNU Make 4.1。

2 个答案:

答案 0 :(得分:1)

Pattern Intro部分的最后一段解释了这一点:

  

模式规则可能有多个目标。与普通规则不同,这并不会使用相同的先决条件和配方来执行许多不同的规则。如果模式规则具有多个目标,则make知道规则的配方负责制作所有目标。配方只执行一次以制作所有目标。

您无法编写具有许多不同模式目标的模式规则,因此make将为每个目标运行一次配方。这不是它的工作原理。

你可以这样做,对于你非常简单的情况:

FILETYPES := $(sort $(suffix $(FILES)))

$(foreach T,$(FILETYPES),$(eval build/%$T: ; mkdir -p $$(@D); echo "hello!" > $$@))

答案 1 :(得分:0)

有一个很好的解决方案:使用普通(非模式)多个目标 规则$(FILES):;rule并定义要调整的模式特定变量值 规则到文件扩展名。