tabula.alba
tabula.alba

Reputation: 3

Dependencies not being made in makefile

I've been trying to get the following makefile to work.

INCLUDE=Include/
LIBRARY=Lib/
CC=g++

UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
    LIBRARIES=-lGLEW -framework OpenGL -framework GLUT
else
    LIBRARIES=-lGL -lglut -lGLEW
endif

SRC := $(shell find -name *.cpp | tr '\n' ' ')

all: release debug

.PHONY: init

init:
    @mkdir -p build/release/object
    @mkdir -p build/debug/object

debug: init
debug: CC = g++ -g
debug: BUILD_DIR = build/debug
debug: makegeneral

release: init
release: CC = g++
release: BUILD_DIR = build/release
release: makegeneral

makegeneral: OBJ = $(SRC:./src/%.cpp=$(BUILD_DIR)/object/%.o)
makegeneral: $(OBJ)
    $(CC) -I$(INCLUDE) -L$(LIBRARY) $(OBJ) $(LIBRARIES) -o VoxPop   
    @rm -rf $(BUILD_DIR)/shaders
    @mkdir -p $(BUILD_DIR)/shaders
    @cp -r src/shaders/* $(BUILD_DIR)/shaders

$(BUILD_DIR)/object/%.o: src/%.cpp
    $(CC) -I$(INCLUDE) -L$(LIBRARY) -o $@ -c $<

.PHONY: clean
clean:
    @rm build/debug/object/* build/release/object/*

Essentially, it sets a few variables specific to a debug build and a release build and then calls a common target, makegeneral. When I run make, I get the following output:

g++ -IInclude/ -LLib/ build/release/object/VoxPop.o build/release/object/Utils.o -lGL -lglut -lGLEW -o VoxPop   
g++: error: build/release/object/VoxPop.o: No such file or directory
g++: error: build/release/object/Utils.o: No such file or directory
make: *** [makegeneral] Error 1

When I echo out SRC and OBJ at the beginning of makegeneral, they appear to be correct. It seems that the problem is with the dependencies for makegeneral, since the rule for compiling object files is never invoked and no there is no "No rule to make target..." message spit out.

For reference, this is what I get when I echo out SRC and OBJ at the beginning of makegeneral.

SRC: ./src/VoxPop.cpp ./src/Utils.cpp
OBJ: build/release/object/VoxPop.o build/release/object/Utils.o

Upvotes: 0

Views: 86

Answers (1)

Etan Reisner
Etan Reisner

Reputation: 80992

BUILD_DIR is not set at the top level so expands to the empty string in the pattern rule. This is also the reason (I believe) for why make isn't failing on unbuildable prereqs. There aren't even any rules for how to do so (beyond the built-in rules). (Though I don't have access to a machine with make at the moment to test my theories.)

I'm also don't believe (though I can't test at the moment) that make will run your makegeneral target twice in this configuration to get you what you want. I believe you will only get it run once with whichever target make chooses to build first (the first listed I believe so in this case release).

Upvotes: 1

Related Questions