1

I have test project folder structure view:

TOPDIR
├── a
│   └── a.c
├── b
│   └── b.c
├── c
│   └── c.c
└── makefile

I wrote a test makefile:

CC        := gcc
LD        := ld

MAKE_DIR = $(PWD)
MODULES := a b c
SRC_DIR := $(addprefix ${MAKE_DIR}/,$(MODULES))

SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c))
OBJ := $(patsubst %.c,%.o,$(SRC))

INCLUDES := $(addprefix -I,$(SRC_DIR))

vpath %.c $(SRC_DIR)

define make-goal
$1/%.o: %.c
    $(CC) $(INCLUDES) -c $$< -o $$@
endef

all:
    $(foreach sdir,$(SRC_DIR),$(eval $(call make-goal,$(sdir))))

during the make, it just STOPPED and shows:

makefile:37: *** prerequisites cannot be defined in command scripts.  Stop.

the line 37 is:

$(foreach sdir,$(SRC_DIR),$(eval $(call make-goal,$(sdir))))

what is wrong with my makefile?

How Chen
  • 1,340
  • 2
  • 17
  • 37

1 Answers1

1

You are expanding make-goal inside a command. Just move it outside:

all: $(OBJ)

$(foreach sdir,$(SRC_DIR),$(eval $(call make-goal,$(sdir))))

Note that defining a recipe, then using foreach-eval-call is overkill in this case. A pattern rule will do:

all: $(OBJ)

%.o: %.c
    $(CC) $(INCLUDES) -c $< -o $@

EDIT:

You can even get away without a pattern rule, using Make's implicit rule for compiling C files:

CFLAGS += $(INCLUDES)

all: $(OBJ)
Beta
  • 96,650
  • 16
  • 149
  • 150
  • many thanks for you help, I forgot to put `$(OBJ)` after `target`, can you also help me on my other question? http://stackoverflow.com/questions/21305590/patsubst-did-not-translate-c-to-o – How Chen Jan 24 '14 at 04:15