Reputation: 339
here is my .c and .o files hierarchy:
---/src/IRBuild/main.c
func1.c
func2.c
---/inclue/main.h
func1.h
func2.h
---/build/IRBuild/main.o
func1.o
func2.o
irbuild
Below is my Makefile under ~/src/IRBuild/, I had build compile dependency with .c and .h files, which means whenever .c or .h files are changed. "make" will rebuild the object files. BUT because I output .o files to ~/build/IRBuild/, instead of current directory, "make" will rebuild all the .o files everytime I do make.
How should I build dependencies with .o files in other directories? Only re-compile the particular file when it's .c, .h, or .o file changed?
Stuck here for two days, thanks a lot!
EXE=irbuild
# G++ as default compiler
CC=g++
# Compile time flags
CXXFLAGS = -g -Wall
# Library paths in addition to /usr/lib
LFLAGS=-std=c++0x
# Libraries to link into executable:
#LIBS = -lmylib -lm
# Include files directory other than /usr/include
INCLUDES=-I../../include/
SRC=$(wildcard *.cpp)
OBJ=$(SRC:.cpp=.o)
DEP=$(OBJ:.o=.d)
BUILD=../../build/IRBuild
TESTS=../../tests/
OBJS :=$(foreach obj, $(OBJ), $(BUILD)/$(obj))
.PHONY: depend clean
all: $(EXE)
cp $(EXE) $(TESTS)
$(EXE): $(OBJ)
$(CC) $(CXXFLAGS) $(LFLAGS) $(INCLUDES) -o $(EXE) $(OBJS)
.cpp.o:
$(CC) $(CXXFLAGS) $(LFLAGS) $(INCLUDES) -c $< -o $(BUILD)/$@
clean:
rm -f $(OBJS) $(DEP) $(EXE)
depend: .depend
.depend: $(SRC)
rm -f ./.depend
$(CC) $(CXXFLAGS) $(LFLAGS) $(INCLUDES) -MM $^ -MF ./.depend;
include .depend
Upvotes: 2
Views: 1849
Reputation: 80911
You are violating rule 2 from http://make.mad-scientist.net/rules.html
which is why it rebuilds them all the time it thinks they don't exist. (Listing $(OBJ)
in the prereqs and $(OBJS)
in the recipe linking line is also a bit of a makefile "smell".)
You need to use a rule that correctly maps from your target files to their prerequisites.
Either manually or using vpath
.
There are a number of ways to make the manual method work depending on how much effort you want to put in to setting things up. The vpath
method is likely to be a fair bit easier.
Using vpath
should just require using $(OBJS)
as the $(EXE)
prereqs and then adding vpath %.cpp .
and vpath %.h ../../include
or something like that.
Upvotes: 1