Reputation: 12445
I've this folder structure
project
|_src
| |_test
| |_main.cpp
|_Makefile
This is my makefile (trying to adapt from this link):
CC = g++
RM = rm
WFLAGS = -c -Wall -W
LDFLAGS =
SRCTESTD = src/test
EXECUTABLE = test
OBJD = .obj
DEPD = .dep
SRCSTEST = $(SRCTESTD)/main.cpp
OBJECTSTEST = $(patsubst %.cpp, $(OBJD)/test/%.o, $(notdir $(SRCSTEST)))
DEPDSTEST = $(patsubst %.cpp, $(DEPD)/test/%.d, $(notdir $(SRCSTEST)))
all: $(SRCSTEST) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTSTEST)
$(CC) $(LDFLAGS) $(OBJECTSTEST) -o $@
.cpp.o:
$(CC) $(WFLAGS) $< -o $@
It does not work, and I've this error
make: *** No rule to make target `.obj/test/main.o', needed by `test'. Stop.
What I'm doing wrong? Sorry for trivial question, but I'm a make newbie.
Upvotes: 0
Views: 199
Reputation: 10506
The link shows outdated methods, such as suffix rules. Making dependencies can also be done during compilation by gcc/g++.
As for the rest, here is it :
EXE := test
SRCDIR := src
OBJDIR := .obj
SRC := $(shell find $(SRCDIR) -name "*.cpp")
OBJ := $(SRC:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
DEP := $(OBJ:.o=.d)
LDLIBS := # -l flags
LDFLAGS := # -L flags
CPPFLAGS := -MMD -MP # -I flags also
CXXFLAGS := -W -Wall # no -c flag here
.PHONY: all clean fclean re
all: $(EXE)
clean:
$(RM) -r $(OBJDIR)
fclean: clean
$(RM) $(EXE)
re: fclean all
-include $(DEP)
$(EXE): $(OBJ)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
@mkdir -p $(@D)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<
No redefinition of internally defined variables, no suffix rules, correct linking step and dependencies generation.
Update: To avoid calling mkdir
for every source file, one should use order-only prerequisites and the special target .SECONDEXPANSION
.
Change this block:
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
@mkdir -p $(@D)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<
To this:
.SECONDEXPANSION:
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp | $$(@D)/
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<
%/:
mkdir $*
Upvotes: 2
Reputation: 6707
The error means make can't find a correct rule to build your object files. Your tree structure lacks some informations: only one file ? Where are the others ? Anyway, here are some hints:
In the last two lines, you are using an obsolete feature of make: suffix rules. I suggest you switch to a pattern rule, which is functionaly equivalent. Say something like:
%.o: %.cpp
$(CXX) $(CXXFLAGS) $< -o $@
Another thing (that shouldn't be a problem here): you are using the variable CC
which is internally defined as the default C compiler. It's okay because you redefine it, but as your sources seem to be C++ files, why not use the variable CXX
, that is internally defined as the C++ compiler ?
Lastly, to make sure your set of files are correctly defined, you can print them with a dummy show
target, see here.
show:
@echo "OBJECTSTEST=$(OBJECTSTEST)"
...
Upvotes: 2