when I tried to compile a program with make, something wrong occurs with the following code:
INC_DIR = ./include
BIN_DIR = ./bin
SRC_DIR = ./src1 ./src2 ./src3
OBJ_DIR = ./obj
SRC = $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c))
OBJ = $(patsubst %.c,${OBJ_DIR}/%.o,$(notdir ${SRC}))
TARGET1 = main
BIN_TARGET1 = ${BIN_DIR}/${TARGET1}
CC = gcc
CFLAGS = -g -Wall -I${INC_DIR}
CFLAGS += -DLOG_USE_COLOR
${BIN_TARGET1}:${OBJ}
$(CC) $(OBJ) -o $@
${OBJ_DIR}/%.o:$(foreach dir,$(SRC_DIR),$(dir)/%.c)
$(CC) $(CFLAGS) -c $< -o $@
.PHONY:clean
clean:
rm -rf ${BIN_TARGET1}
rm -rf ${OBJ_DIR}/*.o
@echo ${SRC}
With make, the result is: make: *** No rule to make target 'obj/main.o', needed by 'bin/main'. Stop. Do not understand what problem is. Thanks a lot!
The rule ${OBJ_DIR}/%.o:$(foreach dir,$(SRC_DIR),$(dir)/%.c)
, when applied to main.o, says that main.o
depends on src1/main.c
, src2/main.c
and src3/main.c
so even make obj/main.o
will fail with:
make: *** No rule to make target 'obj/main.o'. Stop.
Here are 3 alternatives:
${OBJ_DIR}/%.o: src1/%.c
$(CC) $(CFLAGS) -c $< -o $@
${OBJ_DIR}/%.o: src2/%.c
$(CC) $(CFLAGS) -c $< -o $@
${OBJ_DIR}/%.o: src3/%.c
$(CC) $(CFLAGS) -c $< -o $@
You can use a template to generate these (left as exercise for user).
SRC_DIR = ./src1 ./src2 ./src3
VPATH = $(SRC_DIR)
${OBJ_DIR}/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
src/
directory to avoid possible future name clash when you compile files from 3 different directories into obj/
.