Makefile 宏修饰符
Makefile macro modifier
我对 Makefile 中的以下宏修饰符感到非常困惑,
TOOLS = $(TOOL_ROOTS:%=$(OBJDIR)%$(TOOL_SUFFIX))
这里
TOOL_ROOTS=some filename prefixes
OBJDIR=$HOME/obj/
TOOL_SUFFIX=.so
谁能告诉我这行到底是什么意思?
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.
A substitution reference substitutes the value of a variable with alterations that you specify. It has the form ‘$(var:a=b)’ (or ‘${var:a=b}’) and its meaning is to take the value of the variable var, replace every a at the end of a word with b in that value, and substitute the resulting string.
When we say “at the end of a word”, we mean that a must appear either followed by whitespace or at the end of the value in order to be replaced; other occurrences of a in the value are unaltered. For example:
foo := a.o b.o c.o
bar := $(foo:.o=.c)
sets ‘bar’ to ‘a.c b.c c.c’. See Setting Variables.
A substitution reference is actually an abbreviation for use of the patsubst expansion function (see Functions for String Substitution and Analysis). We provide substitution references as well as patsubst for compatibility with other implementations of make.
Another type of substitution reference lets you use the full power of the patsubst function. It has the same form ‘$(var:a=b)’ described above, except that now a must contain a single ‘%’ character. This case is equivalent to ‘$(patsubst a,b,$(var))’. See Functions for String Substitution and Analysis, for a description of the patsubst function.
For example:
foo := a.o b.o c.o
bar := $(foo:%.o=%.c)
sets ‘bar’ to ‘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
这对我来说更有意义。
我对 Makefile 中的以下宏修饰符感到非常困惑,
TOOLS = $(TOOL_ROOTS:%=$(OBJDIR)%$(TOOL_SUFFIX))
这里
TOOL_ROOTS=some filename prefixes
OBJDIR=$HOME/obj/
TOOL_SUFFIX=.so
谁能告诉我这行到底是什么意思?
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.
A substitution reference substitutes the value of a variable with alterations that you specify. It has the form ‘$(var:a=b)’ (or ‘${var:a=b}’) and its meaning is to take the value of the variable var, replace every a at the end of a word with b in that value, and substitute the resulting string.
When we say “at the end of a word”, we mean that a must appear either followed by whitespace or at the end of the value in order to be replaced; other occurrences of a in the value are unaltered. For example:
foo := a.o b.o c.o bar := $(foo:.o=.c)
sets ‘bar’ to ‘a.c b.c c.c’. See Setting Variables.
A substitution reference is actually an abbreviation for use of the patsubst expansion function (see Functions for String Substitution and Analysis). We provide substitution references as well as patsubst for compatibility with other implementations of make.
Another type of substitution reference lets you use the full power of the patsubst function. It has the same form ‘$(var:a=b)’ described above, except that now a must contain a single ‘%’ character. This case is equivalent to ‘$(patsubst a,b,$(var))’. See Functions for String Substitution and Analysis, for a description of the patsubst function.
For example:
foo := a.o b.o c.o bar := $(foo:%.o=%.c)
sets ‘bar’ to ‘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
这对我来说更有意义。