Makefile附加到变量以用于先前的依赖项

时间:2017-09-01 09:53:06

标签: makefile gnu-make

我有一个命令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。

3 个答案:

答案 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 := ... }依赖于all2target1,并自动更新target2