我有一个规则something
,适用于变量VAR
。我还有另一条规则something-all
,需要运行something
,VAR
设置为vars
中的每个值。
vars = hello world
something:
echo $(VAR)
something-all:
$(foreach VAR,$(vars),something)
这不起作用,我得到
noob@work:~/Desktop$ make something-all
something something
make: something: No such file or directory
make: *** [something-all] Error 1
它应该打印hello\nworld
。
我过去通过从VAR
检索%
来使用通配符规则执行此操作,但感觉这是错误的方法。这看起来像这样:
vars = hello world
all: $(foreach VAR,$(vars),something-$(VAR))
something-%:
echo $*
答案 0 :(得分:3)
以下内容应解决您的问题
使用foreach (在sparc-solaris 2.8和windows上尝试使用GNU Make 3.80)
vars = hello world
something:
echo $(VAR)
something-all:
for i in $(vars); do $(MAKE) something VAR=$$i || exit 1; done
使用shell for-loop (尝试使用GNU Make 3.80和cc make on sparc-solaris 2.8)
XMLTABLE
答案 1 :(得分:3)
TL; DR:如果你想编制make,请删除GNU Make支持BSD Make。
这是个人推荐。虽然BSD Make似乎比GNU Make更受限制,因为它提供的编程设施较少,但它是much easier to program并且有few unique killer features。这就是为什么我建议使用GNU Make和BSD Make的另一种解决方案的解决方案:
使用GNU Make,您可以write a macro来定义目标。在Makefile中定义序列的规范方法是将序列的步骤作为依赖项添加到目标,如下面的代码片段所示:
vars= hello world
define something_t =
something: something-$(1)
something-$(1):
@echo $(1)
endef
$(foreach _,$(vars),$(eval $(call something_t,$_)))
建议使用此组织(而不是仅定义一个目标),因为如果中断序列,您可以使用它来使任务易于恢复。 Makefile describes a job,其进度完全由文件系统的状态描述。如果每个步骤都与一个文件相关联,那么任务就很容易恢复,通常是一个编译对象,但有时也是一个空文件,触摸它表示已经通过了重要的检查点。
使用辅助宏是一种灵活的解决方案,可以适应更复杂的任务,而不仅仅是回显名称。请注意,这适用于最新版本的GNU Make(4.1)。在GNU Make 3.81上,您应该从宏定义中删除等号。
如果这是一个选项,我建议不要使用GNU Make并将其替换为BSD Make,即way easier to program:has a short and to the point documentation,而GNU Make的文档非常详细有点不清楚,BSD Make有复杂规则集(FreeBSD Build system或BSD Owl)的工业级实例,它有一个简单且可预测的宏语言。
vars= hello world
something:
.for _var in ${vars}
echo ${_var}
.endfor
这可以演变为支持更复杂的任务,只需通过适应的命令替换echo
或使用中间步骤。
在这个略微更高级的变体中,我们允许用户覆盖我们自己的配方,以构建目标something-hello
和something-world
。
对于列表中的每个项目,如果目标something-*
尚不存在,则创建目标something
,并将其添加到something
的依赖项中。仅当something-hello
未定义时,才会发生定义这些目标的整个操作。因此,这些宏的用户可以:
something-world
和something
vars = hello world
.if!target(depend)
.for _var in ${vars}
.if!target(something-${_var})
something-${_var}:
echo ${_var}
.endif
something: something-${_var}
.endfor
.endif
。如果我们想为Make编写有用的,可重用的宏,那么实现这样的自定义可能性是必需的。不幸的是,这种自定义是nearly impossible in GNU Make。
{{1}}
答案 2 :(得分:2)
这是一种方法:
VARS := hello world
THINGS := $(addprefix something-, $(VARS))
allthings: $(THINGS)
something-%:
echo $*
答案 3 :(得分:1)
应该不足为奇
something something
尝试运行foreach
。这正是VAR
扩展为的原因,因为您未在第三个表达式中引用VAR
。
您需要做的只是参考echo
并使用命令,例如vars := hello world
something-all:
$(foreach VAR,$(vars),echo $(VAR);)
$ make
echo hello; echo world;
hello
world
:
make
注意如何用分号链接命令避免分支多个shell或 - GASP! - 递归vars := hello world
something-all:
echo $(foreach VAR,$(vars),$(VAR))
$ make
echo hello world
hello world
调用。它没有比那更好的表现。
或者,如果你的命令接受几个东西作为参数,
echo $(vars)
但这相当于超级简单的\b([A-Za-z]{2,3}(produsero|usero)+[0-9]{1,3})\b
。因此,如果想要改变您的要求以使这个简单的解决方案发挥作用,可能会有所回报。