Reputation: 2164
Note that there are similar questions on SO, however I think my situation is different, moreover my Makefile is extremely simple and straight forward. I am new to Makefile.
Suppose I need to compile a project, that looks like this --
.
├── [4.0K] bin
├── [ 517] Makefile
├── [4.0K] obj
└── [4.0K] src
├── [ 117] func1.cpp
├── [ 76] func2.cpp
├── [ 137] global.h
└── [ 97] main1.cpp
and my Makefile looks like this --
CC := g++
CFLAGS := -g -Wall -std=c++0x
LDFLAGS := -lm
NAMES := func1.cpp func2.cpp main1.cpp
SRC := $(addprefix src/,$(NAMES))
OBJ := $(addprefix obj/,$(NAMES:.cpp=.o))
DEPS := $(OBJ:.o=.d)
.PHONY: clean all debug
all: prog
debug:
$(info $$SRC: ${SRC})
$(info $$OBJ: ${OBJ})
$(info $$DEPS: ${DEPS})
prog: bin/prog
bin/prog: $(OBJ)
$(CC) $^ -o $@
$(OBJ): $(SRC)
$(CC) $(CFLAGS) -I/src/global.h -c $(addprefix src/,$(notdir $(@:.o=.cpp))) -o $@
-include $(DEPS)
clean:
rm -rf bin/*
rm -rf obj/*
Suppose I opened a file func1.cpp
and made some changes. When I invoke make
it compiles all files, but it was supposed to compile only one (func1.cpp
).
How do I fix this ?
Note: I need prog
, bin/prog
for a different reason, also I can't do recipes like obj/%.o: src/%.c
because I might have different target from the subset of the same objects.
Upvotes: 2
Views: 182
Reputation: 303307
When you write a rule like:
$(OBJ): $(SRC)
cmd
which in your case is
obj/func1.o obj/func2.o obj/main.o : src/func1.cpp src/func2.cpp src/main1.cpp
cmd
The prerequisites don't get zipped across. That generates one rule for each target, with all of the prerequisites. That is:
obj/func1.o : src/func1.cpp src/func2.cpp src/main1.cpp
cmd
obj/func2.o : src/func1.cpp src/func2.cpp src/main1.cpp
cmd
obj/main.o : src/func1.cpp src/func2.cpp src/main1.cpp
cmd
Since src/func1.cpp
is a prereq for all of the object files, they all get recompiled.
What you want instead is to use a static pattern rule:
obj/%.o : src/%.cpp
$(CC) $(CFLAGS) -I/src -c $< -o $@
Note that -I
is for include directories, not include files.
Upvotes: 6