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