Makefile: find the position of a word in a variable

In my makefile, I need to make a variable assignment based on the value of a command line variable. for example me:

make var_1=xxx 

where var_1 can have one of 100 possible values. Based on the value of var_1 , I need to assign the value of var_2 in my makefile. I could do:

 ifeq ($(var_1), a) var_2 = A endif ifeq ($(var_1), b) var_2 = B endif 

etc. for all 100 possible combinations var_1 , var_2 . Here a , a , b , b represent some lines. How to do this to avoid 100 if ? I thought to define two variables:

 var_1_values = abcd var_2_values = ABCD 

I can use $(findstring $(var_1),$(var_1_values)) to see if there is $(var_1) among $(var_1_values) , but how to find the position of $(var_1) among all $(var_1_values) ? Then this position should be used to select the corresponding word inside $(var_2_values) .

+4
source share
5 answers

This is a bit kludgey, but if the character you know will not be in any of the values ​​(for example, "_"), you can do this:

 var_1_values = abcd var_2_values = ABCD # 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))) 
+5
source

One way to model associative containers in make is to use computed variables . For instance:.

 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>) 
+4
source

This can be done pretty well using recursion inside GNU make functions as follows:

 _pos = $(if $(findstring $1,$2),$(call _pos,$1,\ $(wordlist 2,$(words $2),$2),x $3),$3) pos = $(words $(call _pos,$1,$2)) 

To use it, you must $(call) use the pos function with two arguments: the item to find, and a list to find it. For instance,

 $(call pos,a,abcdefg) $(call pos,e,abcdefg) $(call pos,g,abcdefg) $(call pos,h,abcdefg) $(call pos,e,)) 

It works by recursing through the $2 argument until it can no longer find the value in $1 . Each time it repeats, it throws off the head of $2 with $(wordlist 2,$(words $2),$2) . Each time it is recurses, it adds x to the returned row, so for each position through $2 there is x up to $1 .

Then it just uses $(words) to count the return length from _pos (number x s).

If you are using a GMSL project, it may be written more accurately to write this as:

 _pos = $(if $(findstring $1,$2),$(call $0,$1,$(call rest,$2),x $3),$3) pos = $(words $(call _$0,$1,$2)) 

Note that here I used $0 , which will contain the name of the current function (the standard GNU make function) and the GMSL rest function to cut the head off the list.

+3
source

There is a smooth way to do this using recursion as follows. First, define a function called pos that finds the position of an element in the list, and then use $(word) to retrieve the corresponding element in another list.

Here pos :

 _pos = $(if $(findstring $1,$2),$(call _pos,$1,\ $(wordlist 2,$(words $2),$2),x $3),$3) pos = $(words $(call _pos,$1,$2)) 

Read this answer to understand how it works: Makefile: find a function that returns a position

Now it’s easy to define a function that finds an item in a list and finds the corresponding item in another list.

 lookup = $(word $(call pos,$1,$2),$3) 

And then try if you choose like this:

 ALPHA := abcdefghijklmnopqrstu vwxyz 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)) 

Make a to-nato function that converts from an alphabet to a NATO alphabet.

+3
source
 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 Output Code: Macrofava Buffer Suffix - xln

+1
source

Source: https://habr.com/ru/post/1401059/


All Articles