我是创建makefile的新手,所以这个问题可能很简单。如果我使用不良的编码实践,我将很高兴能够指出它。
我正在尝试创建一个基于输入变量创建规则的通用makefile。在我发布的最后是一个" minimal"示例
我遇到了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))))