makefile目标上的第二次扩展和替换

makefile目标上的第二次扩展和替换,makefile,expansion,Makefile,Expansion,我正在尝试用替换在makefile中进行第二次扩展。 示例生成文件: # We have src{0..3}.md documents. Generate them with # # for i in src{0..3}.md; do echo "Hello in $i" > $i; done # # doc0.txt and doc2.txt are capitalized and doc1.txt and doc3b.txt are # lowercased. CAP_DOCS

我正在尝试用替换在makefile中进行第二次扩展。 示例生成文件:

# We have src{0..3}.md documents. Generate them with
#
#   for i in src{0..3}.md; do echo "Hello in $i" > $i; done
#
# doc0.txt and doc2.txt are capitalized and doc1.txt and doc3b.txt are
# lowercased.

CAP_DOCS := doc0.txt doc2.txt
LOW_DOCS := doc1.txt doc3.txt
DOCS := $(CAP_DOCS) $(LOW_DOCS)

all: $(DOCS)

.SECONDEXPANSION:
$(CAP_DOCS): $$(@:doc%.txt=src%.md)
    tr '[a-z]' '[A-Z]' < $< > $@

.SECONDEXPANSION:
$(LOW_DOCS): $$(@:doc%.txt=src%.md)
    tr '[A-Z]' '[a-z]' < $< > $@

我还尝试设置
perc=%
,并将
%
字符替换为
$(perc)
,甚至
$(perc)
,因为我认为它在第二次扩展之前尝试扩展它们,但失败了。它没有帮助。

我也无法将
%
隐藏起来,让make with variables工作,尽管这也是我的第一个想法

我能够得到
$(CAP_DOCS):$$(patsubst doc%.txt,src%.md,$$@)
$(LOW_DOCS):$$(patsubst doc%.txt,src%.md,$$$@
工作


我没有尝试过,但我想知道您是否可以将替换引用隐藏在define或其他内容中,以达到相同的效果。

您只需要
.SECONDEXPANSION
一次。它适用于在它之后定义的所有规则。[无关]哇,太糟糕了。有没有办法禁用它?我不知道。是的,这是我避免使用它的主要原因。我不喜欢它的行为改变世界的性质。请阅读GNU
make
手册。上一次使用
$$
符号编写依赖项行并且不想进行二次扩展是什么时候?System V
make
是自动完成的(有时非常有用)。@JonathanLeffler我的观点是,我更不喜欢不需要改变世界的旗帜,因为它们不需要改变世界,而且我很少需要二次扩展,因此不值得一般处理。(还有“定义后的旗帜”)bit对于一个改变世界的标志来说有点笨拙。)没有在测试makefile上尝试它,但在原始版本上确实有效。谢谢
$ make 
Makefile:15: *** target pattern contains no `%'.  Stop.