我希望能够在 make 中拥有多个大小相同的列表,其中一个列表包含文件名,其他列表包含与这些文件相关的信息,并按相同的顺序排列。我希望能够将文件的特定信息传递给构建该文件的程序。例如,如果 X 是文件名列表(例如匹配以下规则中的 %),而 Y 和 Z 是有关这些文件的信息,我希望能够有这样的规则:
%.a: %.b:
myprogram $(Y[$(*)]) $(Z[$(*)]) $< $@
其中$(*)是make变量,等于%匹配的文件名部分。当然,make中的变量不能用[]来索引。
答案1
我确实找到了这个解决方案。唯一的缺点是它需要选择一个列表中不存在的特殊字符。
EMPTY :=
SPACE := $(EMPTY) $(EMPTY)
# Pick a non-space character that NEVER appears in any word in $S. Here we use a comma.
XX := ,
S := This is very funny world and YOU is the funniest of all!
FIND := YOU
$(info Find $(FIND) in $(S))
S := $(XX)$(subst $(SPACE),$(XX),$(S))$(XX)
$(info S is $(S))
S := $(subst $(XX)$(FIND)$(XX),$(XX)$(FIND)$(SPACE),$(S))
$(info S is $(S))
S := $(firstword $(S))
$(info S is $(S))
S := $(subst $(XX),$(SPACE),$(S))
$(info S is $(S))
IDX = $(words $(S))
$(info IDX of $(FIND) is $(IDX))
# Combine into a giant function that can be called.
IDX = $(words $(subst $(XX),$(SPACE),$(firstword $(subst $(XX)$(2)$(XX),$(XX)$(2)$(SPACE),$(XX)$(subst $(SPACE),$(XX),$(1))$(XX)))))
$(info Index of $(FIND) is $(call IDX,$(S),$(FIND)))
# Define a function that returns the list element of the first argument that
# is at the same position as the second argument is in the third argument.
ATIDX = $(word $(call IDX,$3,$2),$1)
因此规则如下:
%.a: %.b
myprogram $(call, ATIDX,$(Y),$(*),$(X)) $(call ATIDX,$(Z),$(*),$(X)) $< $@