我缺少有关隐式规则的信息。这是Makefile(GNU Make 4.2.1)
heimdall /tmp 1670> cat Makefile
PARTS= a b c
.SECONDEXPANSION:
data/events2: $$(patsubst %,$$(@D)/%.ppd,$(PARTS))
/bin/ls -l $^
%/events2: $$(patsubst %,$$(@D)/%.ppd,$(PARTS))
/bin/ls -l $^
以下是准备好的数据来说明情况:
heimdall /tmp 1671> ls -1 data data1
data:
a.ppd
b.ppd
c.ppd
data1:
a.ppd
b.ppd
c.ppd
这里make
使用的是显式规则,其作用与我期望的一样。
heimdall /tmp 1672> make data/events2
/bin/ls -l data/a.ppd data/b.ppd data/c.ppd
-rw-rw-r-- 1 bennett None 0 Feb 4 12:19 data/a.ppd
-rw-rw-r-- 1 bennett None 0 Feb 4 12:19 data/b.ppd
-rw-rw-r-- 1 bennett None 0 Feb 4 12:19 data/c.ppd
最后,这个:
heimdall /tmp 1673> make data1/events2
make: *** No rule to make target 'data1/events2'. Stop.
为什么隐式规则不匹配?我觉得我已经错过了一些基本知识。
谢谢。
-E
答案 0 :(得分:1)
%/events2: $$(patsubst %,$$(@D)/%.ppd,$(PARTS))
这不是与您的样本结构匹配的模式规则。来自docs:
模式规则的先决条件中的
%
代表与目标中的%
匹配的词干。为了应用模式规则,其目标模式必须与所考虑的文件名匹配,并且其所有先决条件(在模式替换之后)必须命名存在或可以创建的文件。这些文件成为目标的先决条件。
但是在您的目标%
中将匹配data1
。但是实际上在前提条件方面没有任何%
可以匹配,因为其中存在的通常是patsubst
函数,目录(词干)被称为$(@D)
。
我尝试使用foreach
函数编写这样的规则:
%/events2: $(foreach part,$(PARTS), %/$(part).ppd)
/bin/ls -l $^
如果您想坚持使用patsubst
,这应该也可以:
%/events2: $(patsubst %,\%/%.ppd,$(PARTS))
/bin/ls -l $^
不是%
用于与目标中的目录名称匹配的目录名,并且使用\
进行了转义,以使其毫不费力地通过patsubst
。
这两种方法在GNU make yield中似乎都进展顺利:
$ make data1/events2
/bin/ls -l data1/a.ppd data1/b.ppd data1/c.ppd
-rw-r--r-- 1 ondrej users 0 Feb 4 22:00 data1/a.ppd
-rw-r--r-- 1 ondrej users 0 Feb 4 22:00 data1/b.ppd
-rw-r--r-- 1 ondrej users 0 Feb 4 22:00 data1/c.ppd