I'm trying to make so that the *.o files are kept in /bin however after running it, the *.o files are not kept.
my file systems is as follows:
> bin
> src
*.cpp
> headers
*.h
makefile
.
CC := g
CFLAGS := -Isrc/headers
NAME := run
SRC := src/
HSRC := $(SRC)/headers/
OBJ := bin/
SOURCES := $(wildcard $(SRC)*.cpp)
DEPS = $(wildcard $(HSRC)*.h)
OBJECTS := $(patsubst $(SRC)*.cpp,$(OBJ)*.o,$(SOURCES))
$(OBJ)/%.o: %.cpp $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
$(NAME): $(OBJECTS)
$(CC) -o $@ $^ $(CFLAGS)
.PHONY: clean
clean:
rm -f $(NAME) $(OBJ)/*.o *~ core $(INCDIR)/*~
CodePudding user response:
Your main, high-level problem is that you are not testing the makefile as you develop it, so the bugs pile up before you know they're there.
The first concrete problem is that your assignment to OBJECTS
is incorrect, and doesn't work the way you think it does. The patsubst
function uses %
, not *
, so it ought to be:
OBJECTS := $(patsubst $(SRC)%.cpp,$(OBJ)%.o,$(SOURCES))
The second is that you have not decided whether OBJ
should contain a trialing slash. It shouldn't, but that's not the point; the point is that you must be consistent. Look here:
OBJ := bin/
...
$(OBJ)/%.o: %.cpp $(DEPS)
...
See the problem? You have written a rule that will match bin//foo.o
but not bin/foo.o
, so Make will never invoke it. We must pick one convention or the other; for purposes of this Answer I will pick this one:
OBJ := bin
Third, when you wrote that rule you appear to have overlooked the fact that you put the source files in their own directory, so we must modify it:
$(OBJ)/%.o: $(SRC)%.cpp $(DEPS)
There is still some room for improvement, but this will work.