makefile:在变量中查找单词的位置

时间:2012-03-12 20:58:31

标签: makefile

在我的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_2aAb代表一些字符串。我该怎么做才能避免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)内的相应单词。

6 个答案:

答案 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