我对我进入的Makefile中的以下宏修饰符感到困惑,
TOOLS = $(TOOL_ROOTS:%=$(OBJDIR)%$(TOOL_SUFFIX))
这里
TOOL_ROOTS=some filename prefixes
OBJDIR=$HOME/obj/
TOOL_SUFFIX=.so
有人能告诉我这条线的实际意义吗?
答案 0 :(得分:1)
TOOL_ROOTS
必须在某个时刻被分配一些除空字符串以外的值,或者什么也不做(我稍后会显示)。
首先,首先只是扩展变量需要我们:
TOOLS = $(TOOL_ROOTS:%=$(OBJDIR)%$(TOOL_SUFFIX))
为:
TOOLS = $(:%=~/obj%.so)
(我们可以立即看到它看起来不正确,因为我会在一瞬间解释不做任何事情)
所以我们假装它有一个值。
TOOL_ROOTS = shovel axe hammer
再次尝试扩展:
TOOLS = $(shovel axe hammer:%=~/obj%.so)
(那个OBJDIR
定义看起来很奇怪。我希望它是~/obj/
或者什么......而忽略了~
在这里是一个糟糕的选择而{{1}会好得多。)
接下来我们需要知道的是语法是什么。那是Substitution Reference。
替换引用将变量的值替换为您指定的更改。它的形式为'$(var:a = b)'(或'$ {var:a = b}'),其含义是取变量var的值,用一个单词的末尾替换每个a b在该值中,并替换结果字符串。
当我们说“在一个单词的末尾”时,我们的意思是必须出现一个后跟空格或在值的末尾才能被替换;值的其他出现不会改变。例如:
$HOME
将'bar'设为'a.c b.c c.c'。请参阅设置变量。
替换引用实际上是使用patsubst扩展函数的缩写(请参阅字符串替换和分析的函数)。我们提供替换引用以及patsubst以与make的其他实现兼容。
另一种类型的替换参考允许您使用patsubst函数的全部功能。它具有与上述'$(var:a = b)'相同的形式,但现在必须包含单个'%'字符。这种情况相当于'$(patsubst a,b,$(var))'。有关patsubst函数的说明,请参阅字符串替换和分析的函数。
例如:
foo := a.o b.o c.o bar := $(foo:.o=.c)
将'bar'设为'a.c b.c c.c'。
所以,第一个foo := a.o b.o c.o
bar := $(foo:%.o=%.c)
匹配变量值中的每个单词的全部(这里是%
),然后用第二部分的扩展替换每个值。
因此shovel axe hammer
变为shovel
等等,我们最终会:
~/objshovel.so
看看我之前对TOOLS = ~/objshovel.so ~/objaxe.so ~/objhammer.so
奇怪的看法是什么意思? OBJDIR
会让我们留下这个:
OBJDIR=~/obj/
对我来说更有意义。