我怀疑这实际上并不能满足您的要求。
$**
不是一个单一的结构;它是紧跟 shell-glob 通配符的特殊 Makefile 变量$*
*
。该行将被重写两次:首先,由 Make,类似于
!../path/to/tools/unifdef --opt1 --opt2 foo* > ../path/to/target/foo\*
然后,通过/bin/sh
,到类似的东西
!../path/to/tools/unifdef --opt1 --opt2 foo.c foo1.c foo2.c fooquux.c \
> ../path/to/target/foo*
然后才被执行。
你没有引用任何上下文,所以我不能比这更具体。不过,这就是为什么我认为这是不对的:
除非你设置.RECIPEPREFIX
,这是我以前从未听说过的功能,否则!
命令开头的 没有任何意义,并且应该导致命令失败,因为没有可执行文件以字面意思命名!../path/to/tools/unifdef
。
第二次出现的反斜杠$**
不会转义$*
(你可以通过写来做到这一点$$*
);它被保留,并转义了 shell-glob 星,因此输出被写入一个字面上命名为 的文件../path/to/target/foo*
,这很奇怪,我认为这不是预期的。
如果目标目录 glob 没有被转义,还会有两个问题:
基于对你想要做什么的疯狂猜测,我认为你可能想要更像这样的东西:
# Resist the temptation to use wildcards. It will be less grief in the long run
# to list each file explicitly.
GENERIC_SOURCES := foo.c foo1.c foo2.c fooquux.c barblurf.c barbaz.c
UNIFDEFED_SOURCES := $(patsubst %.c,$(TARGET)/%-u.c,$(GENERIC_SOURCES))
# The indented lines below must be indented using exactly one hard tab character.
$(UNIFDEFED_SOURCES): %-u.c: %.c
$(TOOLSDIRECTORY)unifdef $(UNIFDEF_ARGUMENTS) $< > $@T
mv -f $@T $@
这不会尝试批量调用unifdef
; 如果每个规则只创建一个输出文件,Make 通常会更快乐。
$(patsubst ...)
和静态模式规则是GNU make特有的功能。我通常提倡可移植性,但在 Make 的情况下,GNU 化身比可移植功能集强大得多,因此值得作为依赖项携带。