Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Made an effort to get the object files in another directory, but that directory would otherwise reflect the source directory tree. Got that to work, but there is a missing piece at the $(OBJ): line (right?), so wether you change the source or not, it recompiles. Have a look.

SRC_PATH=../src/
CC=g++
CFLAGS=-c -Wall
LDFLAGS=-lSDL -lSDL_gfx
INCL=-I $(SRC_PATH)include/
EXE=run

SRC=$(wildcard $(SRC_PATH)*.cpp $(SRC_PATH)game/*.cpp $(SRC_PATH)player/*.cpp)
OBJ=$(subst ../src, ../obj, $(SRC:.cpp=))
OBJ_O=$(addsuffix .o, $(OBJ))

all: $(SRC) $(EXE)

$(EXE): $(OBJ)
    $(CC) $(LDFLAGS) $(OBJ_O) -o $@

$(OBJ):
    $(CC) $(CFLAGS) $(INCL) -o $(addsuffix .o, $@) $(subst ../obj, ../src, $@).cpp

clean:
    rm -rf run $(OBJ_O)

Edit

This works as intended: does not recompile. Also, is much easier to read without the complicated suffixes back and forth. See answers and comments below.

SRC_PATH=../src/
CC=g++
CFLAGS=-c -Wall
LDFLAGS=-lSDL -lSDL_gfx
INCL=-I $(SRC_PATH)include/
EXE=run

SRC=$(wildcard $(SRC_PATH)*.cpp $(SRC_PATH)game/*.cpp $(SRC_PATH)player/*.cpp)
OBJ=$(subst ../src, ../obj, $(SRC:.cpp=.o))

all: $(SRC) $(EXE)

$(EXE): $(OBJ)
    $(CC) $(LDFLAGS) $(OBJ) -o $@

../obj/%.o: ../src/%.cpp
    $(CC) $(CFLAGS) $(INCL) -o $@ $<

clean:
    rm -rf run $(OBJ)
share|improve this question
1  
What exactly is the question? –  ephsmith Jul 11 '12 at 3:09
    
How do you make it not recompile files that are not changed since the last compilation? –  Emanuel Berg Jul 11 '12 at 4:27
add comment

2 Answers 2

up vote 3 down vote accepted

There are several problems:

First, your OBJ variable does not refer to a list of files that are built. E.g., when you have source files src/a.cpp and src/b.cpp, OBJ will contain obj/a and obj/b. So use OBJ_O instead of OBJ.

Second, your target for building the OBJ files does not give dependencies between the .cpp and .o files. It is a problem that you write your rule for creating the .o files in that way, because you can't give dependency info in that line. I would completely rewrite that rule for creating .o files:

../obj/%.o: ../src/%.cpp
    $(CC) $(CFLAGS) $(INCL) -o "$@" "$<"

This builds each .o file separately, and each .o file depends on the corresponding .cpp file.

This is a rule for creating a ../obj/**.o file from every file that matches ../src/**.cpp.

share|improve this answer
    
@UlrichDangel see my updated post. Hope that clears it up. –  daniel kullmann Jul 11 '12 at 11:07
    
I tried both those (the .cpp.o and the % solution): make: No rule to make target ../obj/anim.o, needed by run. Stop. –  Emanuel Berg Jul 11 '12 at 11:20
    
@EmanuelBerg oh, I forgot that you don't compile into ../src/. See my updated answer; the .cpp.o rule format doesn't work in that case. –  daniel kullmann Jul 11 '12 at 11:46
    
Very impressive! Mange tak :) –  Emanuel Berg Jul 11 '12 at 11:55
add comment

To make it clearer:

The main problem is precicely the line $(OBJ):

The problem is that if there is a source file ../src/a.cpp the variable OBJ contains ../obj/a and the rule $(OBJ): means "use the following recipie to build the file ../obj/a". But that's not what the recipie does! (Instead it creates a file ../obj/a.o.)

That's why make will always execute that recipie because it is desperate to create the file ../obj/a as that filename is listed as a depencency in $(EXE): $(OBJ)

share|improve this answer
    
I am aware it lacks the dot and suffix. But if I put it there, how do you get the change of suffix (.o -> .cpp) and the proper path change? (Now this is done with: $(subst ../obj, ../src, $@).cpp - that only works if there is no suffix at all to start with.) –  Emanuel Berg Jul 11 '12 at 11:25
    
Your problem is/was that you were using make incorrectly. If any dependency file has a newer timestamp than the target file (or the target file does not exist) a recipie is exectued. There are many ways to accomplish what you want and the most favourable is Emanuel's. There are implicit rules, or you can make the substitutions inside the recipie, or you simply touch $@. –  Bananguin Jul 11 '12 at 12:25
    
"Your problem is/was that you were using make incorrectly." Really? :) As I understand it, the way I "fetched" the object files collectively made it difficult (impossible?) to express the corresponding source file as a dependency. Anyway that issue solved itself since there was a much better way to refer to the objects. –  Emanuel Berg Jul 11 '12 at 12:30
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.