1

I need to call a function with two parameters inside a foreach loop

define obj-goal
$1: $2
    gcc $(CXXFLAGS) -c $$< -o $$@
endef

Two arguments for the function are coming from two lists

C_FILES:=$(patsubst %.py,%.c,$(SRC_FILES))
OBJ_FILES:=$(patsubst %.py,build/temp.linux-x86_64-2.7/%.o,$(SRC_FILES))

Currently what I did was concatenate the two variables and then split again using two functions first-var and last-var then passed into the required function

first-var = $(firstword $(subst ^, ,$1))
last-var = $(lastword $(subst ^, ,$1))

OC_FLIST:=$(join $(OBJ_FILES),$(patsubst %,^%,$(C_FILES)))
$(foreach filecat,$(OC_FLIST),$(info $(call obj-goal,$(call first-var,$(filecat)),$(call last-var,$(filecat)))))

Is there a better way to do this? like:

$(foreach (ofile, cfile), ($(OBJ_FILES), $(C_FILES)) ,$(eval $(call obj-goal,$(ofile),$(cfile))))
  • 1
    See [this answer](https://stackoverflow.com/questions/7932205/parallel-iteration-over-lists-in-makefile-or-cmake-file/60203826#60203826) – Vroomfondel May 15 '20 at 11:38

2 Answers2

2

There's a much easier way. Use a static pattern rule:

$(OBJ_FILES): build/temp.linux-x86_64-2.7/%.o: %.c
    gcc $(CXXFLAGS) -c $< -o $@ 
Beta
  • 96,650
  • 16
  • 149
  • 150
1

In your particular case, Beta's answer is way better.

The general question of iterating/zipping two lists needs indexing, and, I'm afraid, $(shell seq):

LIST1 := a b c
LIST2 := 1 2 3

test:
    echo $(foreach INDEX, \
                   $(shell seq 1 $(words $(LIST1))), \
                   $(word $(INDEX), $(LIST1)) and $(word $(INDEX), $(LIST2)))
Victor Sergienko
  • 13,115
  • 3
  • 57
  • 91
  • Thank you, yes this will be helpful in other situations. for this eg: `$(foreach INDEX, $(shell seq 1 $(words $(LIST1))), $(info $(call obj-goal, $(word $(INDEX), $(LIST1)), $(word $(INDEX), $(LIST2)))))` – Nalaka Rajamanthri May 13 '20 at 08:37
  • `$(call)` is a code smell in makefile. If you're making callable macros, then you should be doing something else. – Victor Sergienko May 13 '20 at 09:50
  • Sorry, but your last comment is ill-advised. Complexity dosn't go away just by distributing it over several tools or languages, quite the contrary. – Vroomfondel May 15 '20 at 11:30
  • I didn't say it needs to be moved into another language. To be more specific, most times the proper tool for the job is a pattern rule instead of a macro. Macros are harder to debug, they are executed each time any target is run, and `make`'s macro language is poor; its primary language is target rules. – Victor Sergienko May 15 '20 at 20:22