2015-12-11 30 views
3

GNU make manual不擅长解释这部分,我找不到解释或者我无法推断其他地方的信息。makefile中%和*有什么区别

我意识到%是一种通配符,但就是在targetsdependenciescommands上下文%*之间的区别?我可以在哪里使用它,它在所有地方都有相同的含义?

target: dependencies ... 
    commands 

回答

2

通配符*用来简单地生成在当前目录中匹配的文件列表。模式替换字符%是目前可能存在或可能不存在的文件的占位符。

为了扩大从你已经发现了手册中的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

你可以改换说*比赛配套文件,而%比赛任何匹配的文件。

+0

评论设施的这种用法令人不悦。请不要这样做。 – tripleee

+0

Gotcha。请问,如果我问,为什么会皱起眉头?这两个问题都是关于Make的,它是如何影响SO的?另外,我在哪里可以读到关于它被皱眉了? –

+0

http://meta.stackoverflow.com/questions/269588/should-i-invite-other-users-to-answer-my-question-in-comments – tripleee

3

%*都是制作配方行中的普通字符;他们只是传递给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,因为那么词干%将是空的,这是不允许的。