将Makefile附加到先前依赖项的变量
我有一个接受参数列表的命令将Makefile附加到先前依赖项的变量,makefile,gnu-make,Makefile,Gnu Make,我有一个接受参数列表的命令foo。我想根据我正在构建的目标更改传递给foo的参数。我已经尝试附加到特定于目标的变量,但这并不完全符合我的要求 因此,以这个Makefile为例(因为foo是由target1构建的,所以它不起作用): 发生了什么: > make all foo abc target1 target2 > make target1 foo abc target1 > make target2 foo def target2 我想要的是: > make a
foo
。我想根据我正在构建的目标更改传递给foo
的参数。我已经尝试附加到特定于目标的变量,但这并不完全符合我的要求
因此,以这个Makefile为例(因为foo是由target1构建的,所以它不起作用):
发生了什么:
> 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可以并行构建。您的示例缺少许多细节,可能有更好的处理方法(例如,为什么TARGET
是假的?foo
如何依赖于target1
?),一个完整的例子可以准确地显示文件是如何生成的,这将为您提供更好的答案
也就是说,在这种情况下,类似于以下内容的内容应该可以工作
.PHONY: all foo target1 target2
all: foo_args += abc def
all: target1 target2
target1: foo_args += abc
target1: foo
@echo Target1
target2: foo_args += def
target2: foo
@echo Target2
foo:
@echo foo $(sort $(foo_args))
生成特定于目标的变量的问题在于,它们仅在该目标的范围内可用。特别是,如果您正在构建一个具有多个依赖项的目标,那么一次只能下一个依赖项,foo_args
只会在您恰好从中调用的foo
树的一侧反映目标
另一种解决方案可能是在makefile的顶部使用类似以下内容的内容:
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
可以在全球范围内使用。但这仍然存在可伸缩性问题——如果要创建一个新的目标all2:target1 target2
,则必须将foo\u args\u all2:=…
添加到makefile中(您无法自动检测到all2
依赖于target1
或target2
,并自动更新foo_args
。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
但是,如果你做了make target1 target2
,它将输出foo abc
或foo def
中的一个。这是我现在拥有的一个更简单的版本,它几乎满足了我的需要。我希望有一个更优雅、更可扩展的解决方案,但如果没有人给出更好的答案,我会在几天内接受这个答案。
$ 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