我对创建 makefile 很陌生,所以这个问题可能是微不足道的。如果我使用了糟糕的编码实践,我将不胜感激。
我正在尝试创建一个基于输入变量创建规则的通用 makefile。在我的帖子末尾是一个“最小”的例子。
我有2个问题。
在第 35 行,我实例化了 meta_template。我希望变量 $(Dirs) 被扩展,然后使用 $(Dirs) 的每个条目调用 meta_template。但它只会扩展到倒数第二个,即。make 的结果以:
make: *** No rule to make target 'Dir03Target01Tag01', needed by 'Dir03'. Stop.
在第 21 行,我想创建一个快捷规则,该规则将所有标签都作为给定示例的先决条件。例如:
Dir01Target02: Dir01Target02Tag04 Dir01Target02Tag05
首先,我很困惑我不能使用
$($$(1)Tags)
但必须使用$$($$(1)Tags)
才能访问相应的标签。(例如存储在 Target01Tags 中)。使用
$(addprefix)
似乎没有像我预期的那样扩展,即结果make Dir01Target01
是:Create Rule Dir01Target01 with Dir01Target01Tag01 Tag02 Tag03
我期望它在哪里:
Create Rule Dir01Target01 with Dir01Target01Tag01 Dir01Target01Tag02 Dir01Target01Tag03
编辑:我找到了问题 2 的答案。我已经$(addprefix $(1)$$(1),$$($$(1)Tags))
更改为$$(addprefix $(1)$$(1),$$($$(1)Tags))
. 我认为这是因为这需要在 2 次运行中扩展。所以在第一次运行之后$(addprefix Dirxx$(1),$($(1)Tags))
仍然存在。
提前致谢。
# Targets to compile
Targets = Target01 Target02
# Tags to add to Targets
Target01Tags = Tag01 Tag02 Tag03
Target02Tags = Tag04 Tag05
# Some List (in the actual makefile a list of directories $(wildcard NumeratedDir*))
Dirs = Dir01 Dir02 Dir03
all: $(Dirs)
define meta_template
$(1): $(foreach target,$(Targets),$(foreach tag,$($(target)Tags),$(1)$(target)$(tag)))
define compile_meta
# $(1) 1st argument of meta_compile (<Dirs>xx, eg Dir03)
# $$(1) 1st argument of compile_template (<Targets>, eg Target01)
$(1)$$(1): #$(addprefix $(1)$$(1),$($$(1)Tags))
@echo Create Rule $(1)$$(1) with $(addprefix $(1)$$(1),$$($$(1)Tags)) <---- Line21
endef
$(foreach target,$(Targets),$(eval $(call compile_meta,$(target))))
define compile_template
# $(1) 1st argument of meta_compile (<Dirs>xx, eg Dir03)
# $$(1) 1st argument of compile_template (<Targets>, eg Target01)
# $$(2) 2nd argument of compile_template (<Targets>Tags, eg Tag01)
# create rule using arguments (eg Dir03Target01Tag01)
$(1)$$(1)$$(2):
@echo Create Rule $(1)$$(1)$$(2)
endef
$(foreach target,$(Targets),$(foreach tag,$($(target)Tags),$(eval $(call compile_template,$(target),$(tag))))) <--- Line35
endef
$(foreach prog,$(Dirs),$(eval $(call meta_template,$(prog))))