GNU make
manual不擅长解释这部分,我找不到解释或者我无法推断其他地方的信息。makefile中%和*有什么区别
我意识到%
是一种通配符,但就是在targets
,dependencies
和commands
上下文%
和*
之间的区别?我可以在哪里使用它,它在所有地方都有相同的含义?
target: dependencies ...
commands
GNU make
manual不擅长解释这部分,我找不到解释或者我无法推断其他地方的信息。makefile中%和*有什么区别
我意识到%
是一种通配符,但就是在targets
,dependencies
和commands
上下文%
和*
之间的区别?我可以在哪里使用它,它在所有地方都有相同的含义?
target: dependencies ...
commands
通配符*
用来简单地生成在当前目录中匹配的文件列表。模式替换字符%
是目前可能存在或可能不存在的文件的占位符。
为了扩大从你已经发现了手册中的Wildcard pitfall例如,
objects = *.o
简单地分配给变量相当无用的文字值*.o
- 这大概取决于字面上命名的文件的目标文件*.c
这当然也不存在。所以你会得到一个错误,和/或不稳定的行为。
到短语的正确方式是一样的东西
objects := $(patsubst %.c,%.o,$(wildcard *.c))
make
本身执行在这种情况下没有通配符扩展,当然,如果你通过文字值*.o
的外壳,那就是当扩张发生(如果有匹配的话),所以这可能会稍微难以调试。 make
将在规则中的目标进行通配符扩展,因此可以说
foo: *.o
和像你预期有它究竟是工作(提供所需的文件,保证在这种依赖性进行评估时存在) 。
相比之下,您可以拥有一个带有模式占位符的规则,该规则将被填入任何匹配的名称,因为make
会尝试查找可用于生成所需依赖关系的配方。有喜欢
%.o: %.c
$(CC) $(CCFLAGS) $^ -o [email protected]
内置规则(这里接近真实的东西),它说“给定的匹配%.c
文件,相应的文件%.o
可以如下产生。”在这里,%
是一个可以被任何东西取代的占位符;所以如果它适用于现有文件foo.c
它说明如何可以生成foo.o
。
你可以改换说*
比赛每配套文件,而%
比赛任何匹配的文件。
%
和*
都是制作配方行中的普通字符;他们只是传递给shell。
%
表示模式替换中的文件“干”,如在$(patsubst %.o,%.c,$(OBJS))
中。模式%.o
适用于$(OBJS)
中的每个元素,并且%
捕获匹配的部分。然后在替换模式%.c
中,所捕获的部分被替换为%
,并且替换列表出现在patsubst
之外作为返回值。
*
在$(wildcard ...)
运算符的参数中很有用,它类似于shell在匹配文件系统中的某些路径时的动作。
在patsubst
的左侧,其中%
表示匹配,它类似于*
,因为它匹配某些字符。但是,%
有一些限制,比如它只能出现一次!例如,虽然我们可以扩展通配符*/*.c
,当然,我们不能像$(patsubst %/%.o,%/foo/%.c,...)
那样有双重模式替换。这个限制可以在GNU Make的某些未来版本中解除,但是据我所知,它现在持有。
同样存在这样%
匹配字符的非空序列和%
之间*
一个微妙的差异。通配符模式fo*o.c
匹配foo.c
。替代模式fo%o.c
确实是不是匹配foo.c
,因为那么词干%
将是空的,这是不允许的。
评论设施的这种用法令人不悦。请不要这样做。 – tripleee
Gotcha。请问,如果我问,为什么会皱起眉头?这两个问题都是关于Make的,它是如何影响SO的?另外,我在哪里可以读到关于它被皱眉了? –
http://meta.stackoverflow.com/questions/269588/should-i-invite-other-users-to-answer-my-question-in-comments – tripleee