我有一个命令foo
,它接受一个参数列表。我想根据我正在构建的目标更改传递给foo
的参数。我已尝试附加特定于目标的变量,但这并不是我想做的......
所以,例如,使用这个Makefile(由于foo是由target1构建的,因此无法工作):
all: target1 target2
foo:
echo foo $(foo_args)
target1: foo_args += abc
target1: foo
echo Target1
target2: foo_args += def
target2: foo
echo Target2
.PHONY: foo target1 target2
会发生什么:
> make all
foo abc
target1
target2
> make target1
foo abc
target1
> make target2
foo def
target2
我想要的是什么:
> make all
foo abc def
target1
target2
> make target1
foo abc
target1
> make target2
foo def
target2
Makefile语法可以特定于GNU make。我还想保持并行性,以便可以并行构建target1和target2。
答案 0 :(得分:1)
John的答案的可扩展变体:
define add_target
foo_args_all += $2
foo_args_$(strip $1) := $2
$1: foo; @echo $$@
foo_targets += $1
endef
all:
$(eval $(call add_target, target1, abc))
$(eval $(call add_target, target2, def))
all: $(foo_targets)
foo:; @echo foo $(sort $(foreach g,$(or $(MAKECMDGOALS), all),$(foo_args_$g)))
.PHONY: all $(foo_targets)
输出:
$ make -f sample.gmk
foo abc def
target1
target2
$ make -f sample.gmk all
foo abc def
target1
target2
$ make -f sample.gmk target1
foo abc
target1
$ make -f sample.gmk target2
foo def
target2
$ make -f sample.gmk target2 target1
foo abc def
target2
target1
$ make -f sample.gmk target1 target2
foo abc def
target1
target2
答案 1 :(得分:0)
您的示例缺少一些细节,可能有更好的处理方式(例如,为什么目标Month Year MonthNo Value
Jan 2016 1 700
Feb 2016 2 800
March 2016 3 900
April 2016 4 750
.
.
Jan 2017 13 690
Feb 2017 14 730
?`{Avg(values(4,5,6) - Value(7)} / Value(7)`
i.e (Average of last 3 months value - current month value) / Current month value
如何依赖PHONY
?),一个完整的示例,准确显示文件的生成方式,将为您提供更好的答案。
那就是说,像这样的东西应该适用于这种情况
foo
答案 2 :(得分:0)
制作特定于目标的变量的问题在于它们仅在该目标的范围内可用。特别是,如果您正在构建具有多个依赖项的目标,那么您一次只能查找一个依赖项,而foo_args
只会反映您正在调用的树一侧的目标{{1}来自。
另一种解决方案可能是在makefile的顶部使用以下内容:
foo
这样做的优点是foo_args_target1 := abc
foo_args_target2 := def
foo_args_all := abc def
foo_args := $(sort $(foreach goal,$(MAKECMDGOALS),$(foo_args_$(goal))))
$(info foo_args is $(foo_args))
可用于全局。这仍然存在可伸缩性问题 - 如果您要创建新目标foo_args
,则必须在makefile中添加all2 : target1 target2
(您无法自动检测到foo_args_all2 := ...
}依赖于all2
或target1
,并自动更新target2
。