在我的makefile中,我需要根据命令行变量值进行变量赋值.例如,我这样做:
make var_1=xxx
Run Code Online (Sandbox Code Playgroud)
哪里var_1可以有100个可能值之一.基于值var_1,我需要var_2在我的makefile中分配一个值.我可以:
ifeq ($(var_1), a)
var_2 = A
endif
ifeq ($(var_1), b)
var_2 = B
endif
Run Code Online (Sandbox Code Playgroud)
等了所有100个可能的组合var_1,var_2.在这里a,A,b,B代表一些字符串.我该怎么做才能避免100的if陈述?我在考虑定义两个变量:
var_1_values = a b c d
var_2_values = A B C D
Run Code Online (Sandbox Code Playgroud)
我可以用$(findstring $(var_1),$(var_1_values)),看看是否$(var_1)是中$(var_1_values),但我怎么找到的位置$(var_1)在所有$(var_1_values)?然后该位置用于选择内部的相应单词$(var_2_values).
这是一个小小的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)))
Run Code Online (Sandbox Code Playgroud)
小智 5
这可以非常巧妙地使用 GNU make 函数中的递归来完成,如下所示:
_pos = $(if $(findstring $1,$2),$(call _pos,$1,\
$(wordlist 2,$(words $2),$2),x $3),$3)
pos = $(words $(call _pos,$1,$2))
Run Code Online (Sandbox Code Playgroud)
要使用它,您可以使用带有两个参数$(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,))
Run Code Online (Sandbox Code Playgroud)
它的工作原理是通过$2参数递归,直到它再也找不到 中的值$1。每次递归时,它都会$2使用$(wordlist 2,$(words $2),$2). 每次递归它都会x向返回的字符串添加一个,以便x每个位置都有一个$2直到$1找到的位置。
然后它只是$(words)用来计算从_pos(xs的数量)返回的长度。
如果您使用 GMSL 项目,则可以更巧妙地将其写为:
_pos = $(if $(findstring $1,$2),$(call $0,$1,$(call rest,$2),x $3),$3)
pos = $(words $(call _$0,$1,$2))
Run Code Online (Sandbox Code Playgroud)
请注意,我$0在这里使用了它将包含当前函数的名称(这是标准的 GNU make 功能)和 GMSL 函数rest以将头部从列表中删除。
小智 5
有一种使用递归的流畅方法,如下所示。首先定义一个被调用的函数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))
Run Code Online (Sandbox Code Playgroud)
阅读此答案以了解其工作原理:Makefile: find function which returns position
现在很容易定义一个函数,它在一个列表中找到一个元素,然后在另一个列表中找到相应的元素。
lookup = $(word $(call pos,$1,$2),$3)
Run Code Online (Sandbox Code Playgroud)
然后尝试是否像这样:
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))
Run Code Online (Sandbox Code Playgroud)
制作一个to-nato从字母表字母转换为北约字母表的函数。
| 归档时间: |
|
| 查看次数: |
1297 次 |
| 最近记录: |