sbunny
sbunny

Reputation: 439

How to replace entries of a makefile variable

I have a variable MY_VAR inside a Makefile defined as MY_VAR = read orange yellow blue green white black. I am trying to write a Makefile function/macro that takes a list of colors as input and replaces them by appending a suffix to them. Inside the Makefile I can do this as MY_NEW_VAR = $(shell echo $(MY_VAR) | sed -e 's/black/blackcolor/' -e 's/red/redcolor/' -e 's/white/whitecolor/') but running into problems when doing this using a function with for loop.

define append_color
for color in $(2); do \
  $(eval $(1) += $(shell echo $(MY_VAR) | sed 's/$$color/$$color$(3)/')); \
done;      
endef  

Here $2 is the list of colors to replace and $(1) will contain the result and $3 contains the suffix to append. Below is the function call inside Makefile:

MY_VAR = read orange yellow blue green white black
$(call append_color,MY_NEW_VAR,black red white,color)    

The makefile returns the following error at the point of call to this function inside the Makefile:

Makefile.mk:50: *** missing separator.  Stop.  

Any suggestions on what I am missing or alternatives for doing the same ?

Thanks

Upvotes: 0

Views: 2529

Answers (2)

Vroomfondel
Vroomfondel

Reputation: 2898

There are several ways how you can accomplish your task: Using the classical patsubst function:

append_color = $(patsubst %,%$(3),$(filter $(2),$(1))) $(filter-out $(2),$(1))
MY_NEW_VAR := $(call append_color,$(MY_VAR),black red white,color)

Or with foreach:

append_color = $(foreach w,$(1),$(if $(filter $(w),$(2)),$(w)$(3),$(w)))
MY_NEW_VAR := $(call append_color,$(MY_VAR),black red white,color)

Upvotes: 2

VannTen
VannTen

Reputation: 461

You could do it this way, using only make functions

define replace
$(foreach color,$2,\
    $(eval $1 := $(subst $(color),$(color)$3,$($1))))

endef

COLOR_LIST := red black green orange

COLOR_TO_REPLACE := black green

$(eval $(call replace,COLOR_LIST,$(COLOR_TO_REPLACE),suf))

$(info $(COLOR_LIST))

You append the suffix to the color one by one, at each expansion of eval. (To break it down, the replace is first expanded to $(foreach color,black green,$(eval COLOR_LIST := $(subst $(color),$(color)suf,$(COLOR_LIST)))) then the eval part is expand in this order.

Note that suf in the call to the macro shall not have any spaces in it, or they will be added too.

Upvotes: 1

Related Questions