0
votes

I need help, simply because I need help:

SRC=src/main.c
OBJ_PATH=bin

OBJS := $(addprefix $(OBJ_PATH)/, $(addsuffix .o, $(notdir $(basename $(SRC)))))
all:$(OBJ_PATH)/target.exe

$(OBJ_PATH)/target.exe: $(OBJ_PATH) $(OBJS)
    $(CC) $(OBJS) -o $(OBJ_PATH)/target.exe


$(OBJ_PATH):
    mkdir -p bin  

$(OBJ_PATH)/%.o:%.c
    mkdir -p bin
    $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

.PHONY: clean
clean:
    rm -f $(OBJ_PATH)/*

when running it gives this: make: *** No rule to make target 'bin/main.o', needed by 'bin/target.exe'. Stop.

If I leave the objects in the same folder as the c files, it works. I just need some help, maybe it is something simple that I am not seeing. Thanks guys.

1

1 Answers

1
votes

This is wrong:

$(OBJ_PATH)/%.o: %.c

When make wants to build a file bin/main.o. It matches the target pattern bin/%.o, with a stem of main (the part that matches the %). After replacing the prerequisite pattern %.c with main, make will try to find the prerequisite main.c.

But, that file doesn't exist and make has no idea how to create it. So, that pattern doesn't match and make tries to find a different pattern that will build bin/main.o, but there isn't one, so make says there's no way to build that target.

You need to make your pattern rule:

$(OBJ_PATH)/%.o: src/%.c

so that when make replaces % in the prerequisite pattern it yields src/main.c, which exists, and this will work.

There are other problems with your makefile; for example this is a bad idea:

$(OBJ_PATH)/target.exe: $(OBJ_PATH) $(OBJS)

You never(*) want to use a directory like $(OBJ_PATH) as a simple prerequisite.

Also, this:

OBJS := $(addprefix $(OBJ_PATH)/, $(addsuffix .o, $(notdir $(basename $(SRC)))))

can be more easily written:

OBJS := $(patsubst src/%.c,$(OBJ_PATH)/%.o,$(SRC))

(*) There can indeed be very specific situations where having a directory as a prerequisite can be useful but they are rare and you shouldn't do it unless you fully understand why it's usually not what you want.