Alex Rivera | Logout

Iterating over lists in Makefiles?

Asked 2009-06-10T20:21:19.823
18

I find I'm writing a lot of Makefiles that could be cleaned up with the use of n-tuple lists. But I can't find any way to do this properly (and cleanly). So far I've only been able to come up with using $(shell ...) and tr, sed, or otherwise non-Makefile standards.

For example, I'd like to do this:

XYZs = \
    dog.c  pull_tail bark  \
    duck.c chase     quack \
    cow.c  tip       moo

all:
    @- $(foreach X Y Z,$(XYZs), \
        $(CC) $X -o bully/$Y ; \
        ln bully/$Y sounds/$Z ; \
    )

Is there a good way to iterate n-tuple lists in Makefiles? Thanks!

Edit
Report

2 Answers

16

I'd check the GNU Make manual on foreach. here are some random snips that I've used in a different project... the example is incomplete, but maybe it will give you some ideas? I might clean this up later if I've got more time...

REMAKE_PROGS:= dog duck cow

XYZs = \
    dog.c  pull_tail bark  \
    duck.c chase     quack \
    cow.c  tip       moo

$(foreach src, $(XYZs), $(eval $MAKE $(src))

$(REMAKE_PROGS):
        @echo "\n# === $@ linking\n"
        $(call compile,$@,$(OBJS_$@),$(CXX),$(MPICXX),$(LDFLAGS) $(LIBS) $(SYSLIBS) $(OTHER_LIB) $(EXTRA_LD_FLAGS))
        @echo "\n# --- $@ compiled\n"

define compile
  @mkdir -p $(dir $(1))
  $(if ${ANNOUNCE},@echo "\n# +++ ${MAKECMDGOALS} compiling\n" $(eval ANNOUNCE=))
  $(call compiler,$(1),NOMPI,$(3),$(4))
  $(eval MY_FLAGS=$(FLAGS_$(1)) $(5))
  $(if $(filter %xlf %xlf90,$(COMPILER_$(1))),$(eval MY_FLAGS:=$(MY_FLAGS:-D%=-WF,-D%)))
  $(strip $(COMPILER_$(1)) $(2) $(MY_FLAGS) -o $(1) )
endef
answered 2009-06-10T21:42:41.720
1

You can use default rules for a set of files with the same extension as in for compiling each c file to an o. Of course you are not restricted to any special file extensions. For compiling a set of .c files you could do it like this:

OBJS = foo.o bar.o baz.o
OUT = myprog

all: $(OBJS)
        $(SILENT) echo "LD $@"
        $(SILENT) $(CPP) -o $(OUT) $^ $(LDFLAGS)

%.o: %.c
        $(SILENT) echo "CC $<"
        $(SILENT) $(CC) $(CCOPTS) -o $@ -c $<
answered 2009-06-10T21:51:56.897

Your Answer