【问题标题】:Makefile macro modifierMakefile 宏修饰符
【发布时间】:2015-05-12 16:54:54
【问题描述】:

我对我遇到的 Makefile 中的以下宏修饰符感到非常困惑,

TOOLS = $(TOOL_ROOTS:%=$(OBJDIR)%$(TOOL_SUFFIX))

这里

TOOL_ROOTS=some filename prefixes
OBJDIR=$HOME/obj/
TOOL_SUFFIX=.so

谁能告诉我这条线的真正含义是什么?

【问题讨论】:

    标签: linux macos build macros makefile


    【解决方案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/ 或其他东西......而忽略了 ~ 在这里是一个糟糕的选择,而 $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
    

    这对我来说更有意义。

    【讨论】:

    • 太棒了,感谢您的精彩解释。我已经阅读了一些教程,但仍然不清楚。我忘了坚持阅读制作手册的基础知识。我的错,它确实以路径分隔符结束。我实际上用示例路径替换了原始路径并忘记放置“/”,我认为 TOOL_ROOTS 是在包含文件或 rues 文件中的其他地方定义的。
    • 你能告诉我这实际上是什么意思吗? "$(SA_TOOLS:%=%$(OBJ_SUFFIX)): %: | dir" OBJ_SUFFIX=.o 我知道它会将 SA_TOOLS 中的所有内容替换为添加了 OBJ_SUFFIX,但是关于 :%:| dir,为什么有一个规则作为来源?我知道其他所有先决条件都做了什么,但在我看来,这里将一个 rool 定义为目标。这里 dir 只是简单地创建一个目录
    • 那(a : b: c 语法)是一个Static Pattern Rule,尽管使用该公式它并没有比仅使用普通规则提供太多目的。 | dir 位是 order-only prerequisite,是的 dir 是(可能是 .PHONY)目标,用于确保输出目录(我假设)存在。
    • 感谢这些现在对我有意义。
    猜你喜欢
    • 1970-01-01
    • 2015-03-08
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 2021-11-06
    • 1970-01-01
    • 2022-06-16
    • 2018-03-04
    相关资源
    最近更新 更多