问题 如何在GNU make中使用模式规则和patsubst时正确转义“%”符号?


我有一个像下面这样的makefile:

m1:
    @echo building m1

m1_:
    @echo building m1_


m2:
    @echo building m2

m2_:
    @echo building m2_

m3_DEPS = m2 m1

SUBSTITUTE=$(patsubst %,%_,$($@_DEPS))
.SECONDEXPANSION:

#%: $$(SUBSTITUTE)
%:  $$(patsubst \%,\%_,$$($$@_DEPS))
    @echo Building $@
    @echo Dependencies are $^

关键是

%:  $$(patsubst \%,\%_,$$($$@_DEPS))

我正在使用模式规则和patsubst,它本身使用百分号。我以为我可以逃脱 % 与...的性格 \,但我仍然没有得到预期的行为。运行“make m3”给出输出

building m2
building m1
Building m3
Dependencies are m2 m1

但是,我希望得到

building m2_
building m1_
Building m3
Dependencies are m2_ m1_

评论那条线和呼叫 patsubst 通过变量间接确实产生了那个输出。

SUBSTITUTE=$(patsubst %,%_,$($@_DEPS))

%: $$(SUBSTITUTE)

此外,我已经测试过使用非模式规则有效,这让我觉得它与模式规则和百分号的交互有关:

m3:  $$(patsubst %,%_,$$($$@_DEPS))

7598
2017-10-07 19:17


起源



答案:


\ 在makefile上下文用于行继续,而不是用于“转义”。为了逃避事情,你将它们隐藏在一个变量中:

PERCENT := %

这个想法是,当一个makefile片段被解析,其中转义字符是有意义的,你逃脱它。

所以,在你的情况下,你必须使用 $$(PERCENT)

$$(patsubst $$(PERCENT),$$(PERCENT)_,$$($$@_DEPS))


14
2017-10-11 17:41



这就像我将整个表达式隐藏在变量中所做的那样,但更直接地回答了这个问题。 - Gavin Smith
对不起,是的,我没注意到你那样做了。我刚刚看到“这似乎不太可能”,我跳过其余部分。 - Mark Galeck


答案:


\ 在makefile上下文用于行继续,而不是用于“转义”。为了逃避事情,你将它们隐藏在一个变量中:

PERCENT := %

这个想法是,当一个makefile片段被解析,其中转义字符是有意义的,你逃脱它。

所以,在你的情况下,你必须使用 $$(PERCENT)

$$(patsubst $$(PERCENT),$$(PERCENT)_,$$($$@_DEPS))


14
2017-10-11 17:41



这就像我将整个表达式隐藏在变量中所做的那样,但更直接地回答了这个问题。 - Gavin Smith
对不起,是的,我没注意到你那样做了。我刚刚看到“这似乎不太可能”,我跳过其余部分。 - Mark Galeck


我不知道从模式规则中隐藏'%'的方法,但在这种情况下你可以解决它:

%: $$(addsuffix _,$$($$*_DEPS))
    @echo Building $@
    @echo Dependencies are $^

1
2017-10-07 20:03





这似乎不可能。

有关一些解决方法,请参阅问题和Beta的答案。


0
2017-10-09 16:24