在我的makefile中,我需要根据命令行变量值进行变量赋值。例如,我这样做:
make var_1=xxx
其中var_1
可以有100个可能的值之一。根据{{1}}的值,我需要在makefile中为var_1
赋值。我能做到:
var_2
对于ifeq ($(var_1), a)
var_2 = A
endif
ifeq ($(var_1), b)
var_2 = B
endif
,var_1
的所有100种可能组合,等等。此处var_2
,a
,A
,b
代表一些字符串。我该怎么做才能避免100个B
语句?我在考虑定义两个变量:
if
我可以使用var_1_values = a b c d
var_2_values = A B C D
查看$(findstring $(var_1),$(var_1_values))
是否属于$(var_1)
,但如何在所有$(var_1_values)
中找到$(var_1)
的位置?然后,该位置用于选择$(var_1_values)
内的相应单词。
答案 0 :(得分:5)
这是一个小小的kludgey,但是如果你知道的符号不会出现任何值(例如“_”),你可以这样做:
var_1_values = a b c d
var_2_values = A B C D
# This will be a_A b_B c_C d_D
LIST1 = $(join $(addsuffix _,$(var_1_values)),$(var_2_values))
var_1 := a
# The filter gives a_A, the subst turns it into A
var_2 = $(subst $(var_1)_,,$(filter $(var_1)_%, $(LIST1)))
答案 1 :(得分:4)
在make中模拟关联容器的一种方法是使用computed variables。 E.g:
var_2.a := A
var_2.b := B
# ...
# lookup
var_2 = ${var_2.${var_1}}
# or, lookup and assign a default value if lookup fails
var_2_or_default = $(or ${var_2.${var_1}},<default-value>)
答案 2 :(得分:3)
这可以使用GNU make函数内部的递归非常顺利地完成,如下所示:
_pos = $(if $(findstring $1,$2),$(call _pos,$1,\
$(wordlist 2,$(words $2),$2),x $3),$3)
pos = $(words $(call _pos,$1,$2))
要使用它,你会$(call)
pos
函数有两个参数:要查找的项目和要找到它的列表。例如,
$(call pos,a,a b c d e f g)
$(call pos,e,a b c d e f g)
$(call pos,g,a b c d e f g)
$(call pos,h,a b c d e f g)
$(call pos,e,))
它通过递归$2
参数来工作,直到它无法再找到$1
中的值。每次递增时,使用$2
将头部关闭$(wordlist 2,$(words $2),$2)
。每次都是recurses,它会在返回的字符串中添加x
,以便通过x
到找到$2
的每个位置都有一个$1
。
然后只使用$(words)
来计算_pos
的回报长度(x
s的数量)。
如果您使用GMSL项目,可以更加顺畅地编写,请将其写为:
_pos = $(if $(findstring $1,$2),$(call $0,$1,$(call rest,$2),x $3),$3)
pos = $(words $(call _$0,$1,$2))
请注意,我在这里使用了$0
,其中包含当前函数的名称(这是标准的GNU make功能)和GMSL函数rest
,以便从列表中删除头部。
答案 3 :(得分:3)
使用递归方法可以顺利完成此操作,如下所示。首先定义一个名为pos
的函数,该函数查找列表中元素的位置,然后使用$(word)
提取另一个列表中的相应元素。
这是pos
:
_pos = $(if $(findstring $1,$2),$(call _pos,$1,\
$(wordlist 2,$(words $2),$2),x $3),$3)
pos = $(words $(call _pos,$1,$2))
阅读此答案以了解其工作原理:Makefile: find function which returns position
现在可以很容易地定义一个函数,该函数在列表中查找元素并在另一个列表中查找相应的元素。
lookup = $(word $(call pos,$1,$2),$3)
然后试试这样:
ALPHA := a b c d e f g h i j k l m n o p q r s t u v w x y z
NATO := alpha beta charlie delta echo foxtrot gamma hotel india\
juliet kilo lima mike november oscar papa quebec romeo\
sierra tango uniform victor whisky yankee zulu
to-nato = $(call lookup,$1,$(ALPHA),$(NATO))
制作一个to-nato
函数,用于将字母表中的字母转换为NATO字母。
答案 4 :(得分:1)
FAB = macrofab
# NOTE: base starts at 1 instead of 0
none := 1
seeed := 1
oshpark := 2
macrofab := 2
pcbng := 3
#NOTE: String must end with a space for word function to work
SUFFIX_DRILLS := "txt xln drl "
.PHONY: gerber
gerber:
@echo $(FAB) drill suffix is $(word $($(FAB)), $(SUFFIX_DRILLS))
make的输出是: macrofab钻头后缀是xln
答案 5 :(得分:0)
这在mingw gnu make 4.3中有效:
define get_index
$(shell \
$(eval _c = 1)\
$(eval _b = n n) \
$(foreach x,$(2), \
$(eval _b += n \
$(eval _c = $(words $(_b)) \
$(if $(filter $(1),$(x)), \
$(eval _r = $(_c)))))) \
echo $(_r) \
$(eval _c =) \
$(eval _b =) \
$(eval _r =) \
)
endef
接受两个参数;要搜索的单词和搜索位置列表。 通过在$(shell ...)中回显来“返回”索引。
示例:
list = cow horse chicken
index = $(call get_index,horse,$(list))
@echo $(index)
# output: 2