Makefile 为什么“make”隐式规则不';t工作“;跨文件夹“;?

Makefile 为什么“make”隐式规则不';t工作“;跨文件夹“;?,makefile,implicit-rule,Makefile,Implicit Rule,我有两个并行的文件夹层次结构,我正试图从*.jsonld JSON/*.jsonld AssociationEvent/*.jsonld Turtle/*.ttl AssociationEvent/*.ttl Turtle/Makefile是这样的: JSONLD = $(wildcard ../JSON/*/*.jsonld) $(wildcard ../JSON/*.jsonld) TTL = $(JSONLD:../JSON/%.jsonld=%.ttl)

我有两个并行的文件夹层次结构,我正试图从
*.jsonld

  JSON/*.jsonld
    AssociationEvent/*.jsonld
  Turtle/*.ttl
    AssociationEvent/*.ttl
Turtle/Makefile
是这样的:

JSONLD = $(wildcard ../JSON/*/*.jsonld) $(wildcard ../JSON/*.jsonld)
TTL    = $(JSONLD:../JSON/%.jsonld=%.ttl)

all: $(TTL)  $(warning JSONLD=$(JSONLD)) $(warning TTL=$(TTL))

%.ttl: ../JSON/%.jsonld
    jsonld format -q $^ | cat prefixes.ttl - | riot -syntax ttl -formatted ttl > $@
$(警告)
打印预期内容,但随后出现错误:

make
Makefile:4: JSONLD=../JSON/AssociationEvent/AssociationEvent-g.jsonld ../JSON/Example_9.8.1-MasterData-complying-with-schema.jsonld
Makefile:4: TTL=AssociationEvent/AssociationEvent-g.ttl Example_9.8.1-MasterData-complying-with-schema.ttl
make: *** No rule to make target 'AssociationEvent/AssociationEvent-g.ttl', needed by 'all'.  Stop.
当前文件夹中的ttl(如
Example_9.8.1-MasterData-compliance-with-schema.ttl
)按预期生成,但对于子文件夹中的ttl(如
AssociationEvent/AssociationEvent-g.ttl
),make表示不知道如何生成它们。打印调试信息显示了这一点(除其他外):


@很抱歉,您的建议无效:

JSONLD = $(wildcard ../JSON/*.jsonld) $(wildcard ../JSON/*/*.jsonld)
TTL    = $(JSONLD:../JSON/%.jsonld=./%.ttl)

all: $(TTL)

$(warning $(TTL))./%.ttl: ../JSON/%.jsonld
    jsonld format -q $^ | cat prefixes.ttl - | riot -syntax ttl -formatted ttl > $@
产生

./AssociationEvent/AssociationEvent-a.ttl ./AssociationEvent/AssociationEvent-c.ttl ...
make: *** No rule to make target 'AssociationEvent/AssociationEvent-a.ttl', needed by 'all'.  Stop.

当目标模式不包含斜杠(通常不包含斜杠)时,文件名中的目录名将从文件名中删除,然后再与目标前缀和后缀进行比较。将文件名与目标模式进行比较后,目录名以及结束它们的斜杠将添加到根据模式规则的先决条件模式和文件名生成的先决条件文件名中。忽略目录只是为了查找要使用的隐式规则,而不是在该规则的应用程序中。因此,“e%t”与文件名src/eat匹配,并以“src/a”作为词干。当先决条件转换为文件名时,将在前端添加stem中的目录,而stem的其余部分将替换为“%”。带有先决条件模式“c%r”的干“src/a”给出了文件名src/car

在本例中,Make希望构建
AssociationEvent/AssociationEvent-g.ttl
,它看到目标模式
%.ttl
,将该规则与stem
AssociationEvent/AssociationEvent-g
匹配,但随后查看先决模式
。/JSON/%.jsonld
(这里是出错的地方)派生先决条件
AssociationEvent/。/JSON/AssociationEvent-g.jsonld
。没有这样的文件,所以Make拒绝这个规则

解释到此为止。目前我能想到的最不可怕的解决方案是放弃模式规则,转而使用生成的规则:

define template
$(1).ttl: ../JSON/$(1).jsonld
    jsonld format -q $$^ ... > $$@
endef

$(foreach X,$(patsubst ../JSON/%.jsonld,%,$(JSONLD)),$(eval $(call template,$(X))))

我读过,但无法调试问题。你一定是某种黑魔法巫师!为什么不确保目标模式有一个斜杠,这样它就不用上面的特殊规则了?将目标模式更改为
/%.ttl
有效吗?您可能还需要更改
TTL
变量。@很抱歉,您的建议无效。见编辑question@MadScientist当前位置这是个好主意,我希望我能想到它。但是(尽管有手册)特殊规则似乎也适用于
/%.ttl
。是的。。。make尝试优雅地处理以下情况:您将
/foo
列为目标,但您有
foo
的规则,反之亦然。。。那可能会在这里碍事。您可以使用
$(CURDIR)/
而不是
/
,看看这是否有效,但它会变得越来越粗糙。
./AssociationEvent/AssociationEvent-a.ttl ./AssociationEvent/AssociationEvent-c.ttl ...
make: *** No rule to make target 'AssociationEvent/AssociationEvent-a.ttl', needed by 'all'.  Stop.
define template
$(1).ttl: ../JSON/$(1).jsonld
    jsonld format -q $$^ ... > $$@
endef

$(foreach X,$(patsubst ../JSON/%.jsonld,%,$(JSONLD)),$(eval $(call template,$(X))))