Need to "make" twice when using vpaths

258 Views Asked by At

I've been getting into programming for the last 2 years or so and I'm finally "breaking out of the console" but as i do so, i also want to become independant from IDEs, therefore, i've been learning make but here's an issue i can't seem to find an answer to concerning "vpath"s

here is my makefile:

vpath %.o obj
vpath %.cpp src
vpath %.h inc

EXE = SDL_Game.exe
OBJS = SDL_Game.o Init.o EventHandler.o

INCDIR = -I"C:\SDL-1.2.15\include" -Iinc
LIBDIR = -L"C:\SDL-1.2.15\lib"
LIBS = -lmingw32 -lSDLmain -lSDL

CFLAGS = $(INCDIR) -Wall
LDFLAGS = $(LIBDIR) $(LIBS) -Wall -mwindows

all: $(EXE)

$(EXE): $(OBJS)
    g++ -o bin/$@ $^ $(LDFLAGS)

%.o: %.cpp
    g++ -o obj/$@ -c $< $(CFLAGS)

SDL_Game.o: SDL_Game.h
Init.o: SDL_Game.h
EventHandler.o: SDL_Game.h

.PHONY: clean

clean:
    rm -f bin/* obj/*

And as i use make the first time i use make i get this result:

C:\...\SDL_Test>make
g++ -o obj/SDL_Game.o -c src/SDL_Game.cpp -I"C:\SDL-1.2.15\include" -Iinc -Wall
g++ -o obj/Init.o -c src/Init.cpp -I"C:\SDL-1.2.15\include" -Iinc -Wall
g++ -o obj/EventHandler.o -c src/EventHandler.cpp -I"C:\SDL-1.2.15\include" -Iin
c -Wall
g++ -o bin/SDL_Game.exe SDL_Game.o Init.o EventHandler.o -L"C:\SDL-1.2.15\lib" -
lmingw32 -lSDLmain -lSDL -Wall -mwindows
g++.exe: error: SDL_Game.o: No such file or directory
g++.exe: error: Init.o: No such file or directory
g++.exe: error: EventHandler.o: No such file or directory
make: *** [SDL_Game.exe] Error 1

And i need to use make a second time to get the program to link. Why is that ? Should i not use "vpaths" Also this is what i get on the second make:

C:\...\SDL_Test>make
g++ -o bin/SDL_Game.exe obj/SDL_Game.o obj/Init.o obj/EventHandler.o -L"C:\SDL-1
.2.15\lib" -lmingw32 -lSDLmain -lSDL -Wall -mwindows

(Success)

1

There are 1 best solutions below

0
MadScientist On BEST ANSWER

You cannot use vpath to find object files. It can only be correctly used to find source files. No makefile recipe should ever build any target other than $@; that variable expands to the file that make expects your recipe to build. If it creates a different file then you're not upholding your end of the contract you've made with make.

You need to change your makefile similar to this:

OBJS = SDL_Game.o Init.o EventHandler.o

EXE = bin/SDL_Game.exe

and:

$(EXE): $(addprefix obj/,$(OBJS))
        $(CXX) -o $@ $^ $(LDFLAGS)

obj/%.o : src/%.cpp
        $(CXX) -o $@ -c $< $(CFLAGS)

There are lots of different ways to do this but this is a start. You should also read http://make.mad-scientist.net/vpath.html